MILESTONE 1¶

Import Necessary Files

In [ ]:
!pip3 uninstall opencv-contrib-python opencv-python -y
!pip3 install opencv-contrib-python
!pip install imutils

import pandas as pd
import numpy as np
import re
import os
import cv2
import random
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
from PIL import Image
import datetime
from tqdm import tqdm
import time
from matplotlib.patches import Rectangle
import csv
from skimage import measure
from skimage.transform import resize
import matplotlib.patches as patches
from tensorflow import keras
import sys
import math
import json
import glob
import io
import h5py
from imutils import paths
import imutils


# Import all the necessary libraries.
random.seed(1)
np.random.seed(1)

import warnings
warnings.filterwarnings(action='ignore', category=FutureWarning)
!pip install pydicom
import pydicom

from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score,confusion_matrix,precision_score,recall_score,f1_score,classification_report, confusion_matrix
from sklearn.metrics import roc_curve, roc_auc_score
from sklearn.preprocessing import LabelBinarizer
from sklearn.feature_extraction.image import extract_patches_2d


from keras import initializers
from keras.initializers import RandomNormal, HeNormal, GlorotNormal
from keras import Model, optimizers
from keras.models import Sequential, load_model, Model
from keras.layers import Conv2D, Flatten, Dense, MaxPooling2D, Dropout , BatchNormalization, GlobalMaxPooling2D
from keras.layers import activation, LeakyReLU, Input, AveragePooling2D, GlobalAveragePooling2D, Lambda
from keras.callbacks import EarlyStopping, ModelCheckpoint,  ReduceLROnPlateau
from keras.optimizers import Adam, SGD, RMSprop, Adadelta, Adagrad, Adamax, Nadam
from keras.wrappers.scikit_learn import KerasClassifier
from keras.preprocessing.image import ImageDataGenerator
from keras.applications import VGG16
from keras.applications.vgg16 import VGG16
from keras.applications import MobileNetV2
from keras.applications.mobilenet_v2 import preprocess_input
from keras.applications import ResNet50, ResNet101, InceptionV3, MobileNet, EfficientNetB0, VGG19
from keras.utils import img_to_array, load_img, to_categorical
from sklearn.model_selection import RandomizedSearchCV

import tensorflow as tf
import pickle


import PIL
import time

from matplotlib.patches import Rectangle

from PIL import Image

import albumentations as A
from albumentations.pytorch.transforms import ToTensorV2

import torch
import torchvision

from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection import FasterRCNN
from torchvision.models.detection.rpn import AnchorGenerator

from torch.utils.data import DataLoader, Dataset
from torch.utils.data.sampler import SequentialSampler

from matplotlib import pyplot as plt
Found existing installation: opencv-contrib-python 4.8.0.76
Uninstalling opencv-contrib-python-4.8.0.76:
  Successfully uninstalled opencv-contrib-python-4.8.0.76
WARNING: Skipping opencv-python as it is not installed.
Collecting opencv-contrib-python
  Using cached opencv_contrib_python-4.8.0.76-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (67.8 MB)
Requirement already satisfied: numpy>=1.21.2 in /opt/conda/lib/python3.10/site-packages (from opencv-contrib-python) (1.23.5)
Installing collected packages: opencv-contrib-python
Successfully installed opencv-contrib-python-4.8.0.76
Requirement already satisfied: imutils in /opt/conda/lib/python3.10/site-packages (0.5.4)
/opt/conda/lib/python3.10/site-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.5
  warnings.warn(f"A NumPy version >={np_minversion} and <{np_maxversion}"
/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:98: UserWarning: unable to load libtensorflow_io_plugins.so: unable to open file: libtensorflow_io_plugins.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so']
caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so: undefined symbol: _ZN3tsl6StatusC1EN10tensorflow5error4CodeESt17basic_string_viewIcSt11char_traitsIcEENS_14SourceLocationE']
  warnings.warn(f"unable to load libtensorflow_io_plugins.so: {e}")
/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:104: UserWarning: file system plugins are not loaded: unable to open file: libtensorflow_io.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so']
caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so: undefined symbol: _ZTVN10tensorflow13GcsFileSystemE']
  warnings.warn(f"file system plugins are not loaded: {e}")
Requirement already satisfied: pydicom in /opt/conda/lib/python3.10/site-packages (2.4.1)

Read CSV files from source data¶

In [ ]:
# Read the CSV files
detailed_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_detailed_class_info.csv')
train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
In [ ]:
print(detailed_df.shape)
print(train_df.shape)
(30227, 2)
(30227, 6)

Observations:

The detailed CSV file contains 30227 entries and 2 columns.

The Train Labels CSV file contains 30227 entries and 6 columns.

Display the dataframe¶

In [ ]:
print(detailed_df.head())
                              patientId                         class

0  0004cfab-14fd-4e49-80ba-63a80b6bddd6  No Lung Opacity / Not Normal

1  00313ee0-9eaa-42f4-b0ab-c148ed3241cd  No Lung Opacity / Not Normal

2  00322d4d-1c29-4943-afc9-b6754be640eb  No Lung Opacity / Not Normal

3  003d8fa0-6bf1-40ed-b54c-ac657f8495c5                        Normal

4  00436515-870c-4b36-a041-de91049b9ab4                  Lung Opacity
In [ ]:
print(train_df.head())
                              patientId      x      y  width  height  Target

0  0004cfab-14fd-4e49-80ba-63a80b6bddd6    NaN    NaN    NaN     NaN       0

1  00313ee0-9eaa-42f4-b0ab-c148ed3241cd    NaN    NaN    NaN     NaN       0

2  00322d4d-1c29-4943-afc9-b6754be640eb    NaN    NaN    NaN     NaN       0

3  003d8fa0-6bf1-40ed-b54c-ac657f8495c5    NaN    NaN    NaN     NaN       0

4  00436515-870c-4b36-a041-de91049b9ab4  264.0  152.0  213.0   379.0       1

Observations:

Detailed dataframe contains Columns - patientId and class.

  • patientId is the unique ID of each patient.
  • class indicates the condition of the chest.

Train dataframe contains Columns - patientId, x, y , width, height and Target.

  • patientId is the unique ID of each patient.
  • x, y, width and height marks the bounding boxes where pneumonia is detected.
  • Target indicates if pnemonia is detected in patient. 0 - no pneumonia, 1 - pneumonia.

Check Unique values of the dataframe¶

In [ ]:
print('Unique Values of the Detailed Dataframe   :', detailed_df['class'].unique())
print('Unique Values of the Train Label Dataframe:', train_df['Target'].unique())
Unique Values of the Detailed Dataframe   : ['No Lung Opacity / Not Normal' 'Normal' 'Lung Opacity']

Unique Values of the Train Label Dataframe: [0 1]
In [ ]:
print('Number of Unique Patient IDs in Detailed Dataframe   : ',detailed_df['patientId'].nunique())
print('Number of Unique Patient IDs in Train Label Dataframe: ',train_df['patientId'].nunique())
Number of Unique Patient IDs in Detailed Dataframe   :  26684

Number of Unique Patient IDs in Train Label Dataframe:  26684

Observations:

  • There are 26684 unique patients.
  • Three class labels - ('No Lung Opacity / Not Normal', 'Normal', 'Lung Opacity' ) indicates the condition of the lungs.
  • Target column has only two categories - 0 - no pneumonia, 1 - pneumonia.
  • There are multiple entries for few patients, each row providing information on the bounding boxes which indicates pneumonia in lungs.

Merge the CSV files into one dataframe¶

In [ ]:
df = pd.concat([train_df,detailed_df["class"]],axis=1,sort=False)
df.head()
Out[ ]:
patientId x y width height Target class
0 0004cfab-14fd-4e49-80ba-63a80b6bddd6 NaN NaN NaN NaN 0 No Lung Opacity / Not Normal
1 00313ee0-9eaa-42f4-b0ab-c148ed3241cd NaN NaN NaN NaN 0 No Lung Opacity / Not Normal
2 00322d4d-1c29-4943-afc9-b6754be640eb NaN NaN NaN NaN 0 No Lung Opacity / Not Normal
3 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 NaN NaN NaN NaN 0 Normal
4 00436515-870c-4b36-a041-de91049b9ab4 264.0 152.0 213.0 379.0 1 Lung Opacity

Observations:

  • The merged dataframe contains bounding box, class and Target information of the patient.

In cases where there is no pneumonia detected, the entries for x, y, width and height contains NANs. Replacing NAN of the bounding boxes with 0¶

In [ ]:
df.fillna(0,inplace=True)

Distribution of patients with Target and Classes¶

In [ ]:
fig, ax = plt.subplots(1, 2, figsize=(12,4))
pd.pivot_table(df,index=["Target"], values=['patientId'], aggfunc='count').plot.bar(title='Distribution of patients with Target', rot=0, color = 'turquoise', ax=ax[0])
pd.pivot_table(df,index=["class"], values=['patientId'], aggfunc='count').plot.bar(title='Distribution of patients with Classes', rot = 8, color = 'turquoise', ax=ax[1])
for i in ax[0].containers:
    ax[0].bar_label(i,)
for i in ax[1].containers:
    ax[1].bar_label(i,)
plt.show();

Observations:

  • There are 20672 patients who do not have pneumonia detected in them.
  • 9555 patients have been reported to have pneumonia with Lung Opacity observed.
  • There are 11821 patients who do not have pneumonia detected in them but there is some abnormality seen in their lungs.
  • 8851 patients do not have pneumonia.

Analyse multiple bounding box distribution for the patients¶

In [ ]:
pd.pivot_table(df, index = ['patientId'], aggfunc ='size')
Out[ ]:
patientId
0004cfab-14fd-4e49-80ba-63a80b6bddd6    1
000924cf-0f8d-42bd-9158-1af53881a557    1
000db696-cf54-4385-b10b-6b16fbb3f985    2
000fe35a-2649-43d4-b027-e67796d412e0    2
001031d9-f904-4a23-b3e5-2c088acd19c6    2
                                       ..
fffb2395-8edd-4954-8a89-ffe2fd329be3    2
fffba05a-1635-4545-9bbd-57ad4cfe8d27    1
fffc95b5-605b-4226-80ab-62caec682b22    1
fffcff11-d018-4414-971a-a7cefa327795    1
fffec09e-8a4a-48b1-b33e-ab4890ccd136    1
Length: 26684, dtype: int64

Observations:

As seen, there are multiple entries for the same patientID. Lets analyse further.

In [ ]:
df[df['patientId'] == '000db696-cf54-4385-b10b-6b16fbb3f985']
Out[ ]:
patientId x y width height Target class
28990 000db696-cf54-4385-b10b-6b16fbb3f985 316.0 318.0 170.0 478.0 1 Lung Opacity
28991 000db696-cf54-4385-b10b-6b16fbb3f985 660.0 375.0 146.0 402.0 1 Lung Opacity

Observations:

  • For example, the patient ID above has two entries. Both the entries indicate Lung Opacity. However, the bounding box details are different indicating there are multiple areas in lungs where pneumonia is detected.
  • These cannot be treated as duplicates and hence cannot be dropped.

Distribution of bounding boxes with patientId¶

In [ ]:
ax = df['patientId'].value_counts().value_counts().plot.bar(figsize=(6,4), title='Distribution of bounding boxes with patientId',
                                                            rot = 0, color = 'turquoise');
plt.yscale('log')
plt.xlabel('No. of Bounding Box')
plt.ylabel('No. of Patients')
for i in ax.containers:
    ax.bar_label(i,)

Observations:

  • 23286 patients have only one entry. This either indicates no bounding box (x, y, width, height are all zeros) or one bounding box where penumonia is detected.
  • 3266 patients have 2 bounding box where penumonia is detected.
  • 119 patients have 3 bounding box where penumonia is detected.
  • 13 patients have 4 bounding box where penumonia is detected.

Read one DCM file and display the metadata¶

In [ ]:
test_Image = pydicom.read_file('/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/0004cfab-14fd-4e49-80ba-63a80b6bddd6.dcm')
test_Image
Out[ ]:
Dataset.file_meta -------------------------------
(0002, 0000) File Meta Information Group Length  UL: 202
(0002, 0001) File Meta Information Version       OB: b'\x00\x01'
(0002, 0002) Media Storage SOP Class UID         UI: Secondary Capture Image Storage
(0002, 0003) Media Storage SOP Instance UID      UI: 1.2.276.0.7230010.3.1.4.8323329.28530.1517874485.775526
(0002, 0010) Transfer Syntax UID                 UI: JPEG Baseline (Process 1)
(0002, 0012) Implementation Class UID            UI: 1.2.276.0.7230010.3.0.3.6.0
(0002, 0013) Implementation Version Name         SH: 'OFFIS_DCMTK_360'
-------------------------------------------------
(0008, 0005) Specific Character Set              CS: 'ISO_IR 100'
(0008, 0016) SOP Class UID                       UI: Secondary Capture Image Storage
(0008, 0018) SOP Instance UID                    UI: 1.2.276.0.7230010.3.1.4.8323329.28530.1517874485.775526
(0008, 0020) Study Date                          DA: '19010101'
(0008, 0030) Study Time                          TM: '000000.00'
(0008, 0050) Accession Number                    SH: ''
(0008, 0060) Modality                            CS: 'CR'
(0008, 0064) Conversion Type                     CS: 'WSD'
(0008, 0090) Referring Physician's Name          PN: ''
(0008, 103e) Series Description                  LO: 'view: PA'
(0010, 0010) Patient's Name                      PN: '0004cfab-14fd-4e49-80ba-63a80b6bddd6'
(0010, 0020) Patient ID                          LO: '0004cfab-14fd-4e49-80ba-63a80b6bddd6'
(0010, 0030) Patient's Birth Date                DA: ''
(0010, 0040) Patient's Sex                       CS: 'F'
(0010, 1010) Patient's Age                       AS: '51'
(0018, 0015) Body Part Examined                  CS: 'CHEST'
(0018, 5101) View Position                       CS: 'PA'
(0020, 000d) Study Instance UID                  UI: 1.2.276.0.7230010.3.1.2.8323329.28530.1517874485.775525
(0020, 000e) Series Instance UID                 UI: 1.2.276.0.7230010.3.1.3.8323329.28530.1517874485.775524
(0020, 0010) Study ID                            SH: ''
(0020, 0011) Series Number                       IS: '1'
(0020, 0013) Instance Number                     IS: '1'
(0020, 0020) Patient Orientation                 CS: ''
(0028, 0002) Samples per Pixel                   US: 1
(0028, 0004) Photometric Interpretation          CS: 'MONOCHROME2'
(0028, 0010) Rows                                US: 1024
(0028, 0011) Columns                             US: 1024
(0028, 0030) Pixel Spacing                       DS: [0.14300000000000002, 0.14300000000000002]
(0028, 0100) Bits Allocated                      US: 8
(0028, 0101) Bits Stored                         US: 8
(0028, 0102) High Bit                            US: 7
(0028, 0103) Pixel Representation                US: 0
(0028, 2110) Lossy Image Compression             CS: '01'
(0028, 2114) Lossy Image Compression Method      CS: 'ISO_10918_1'
(7fe0, 0010) Pixel Data                          OB: Array of 142006 elements

Observations:

  • Few variables like Modality, Rows, Columns, Body Part Examined, etc have same values for all patients. Hence , there is no point in adding it to our dataframe for further EDA.
  • Patient's Name and Patient's ID can be ignored.
  • Patient's Birth Date is hidden due to privacy. There is already Age variable which covers this part.
  • Given the above, we will go ahead with using Sex, Age and View Position to our dataframe and perform EDA on the same.

Merge Annotation from DICOM file into dataframe¶

In [ ]:
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
In [ ]:
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
# Function to read dicom file from a Src Dataframe with PatientId as file name.
def read_metadata(src):
    # Iterate over unique values of patientId and read the dcm file for that patientId
    for n, index in tqdm(enumerate(src['patientId'].unique())):
        data = pydicom.read_file(IMAGE_PATH+ '%s.dcm' % index)
        # copy it to all the rows where the patient Id matches.
        # Retreive "Age, Sex, and Position" information from metadata and copy it to Dataframe.
        src.loc[src['patientId'] == data.PatientID ,'PatientAge'] = pd.to_numeric(data.PatientAge)
        src.loc[src['patientId'] == data.PatientID ,'PatientSex'] = data.PatientSex
        src.loc[src['patientId'] == data.PatientID ,'ViewPosition'] = data.ViewPosition

    return src
In [ ]:
final_df = df
final_df = read_metadata(final_df)
26684it [12:42, 35.01it/s]
In [ ]:
final_df.head()
Out[ ]:
patientId x y width height Target class PatientAge PatientSex ViewPosition
0 0004cfab-14fd-4e49-80ba-63a80b6bddd6 0.0 0.0 0.0 0.0 0 No Lung Opacity / Not Normal 51.0 F PA
1 00313ee0-9eaa-42f4-b0ab-c148ed3241cd 0.0 0.0 0.0 0.0 0 No Lung Opacity / Not Normal 48.0 F PA
2 00322d4d-1c29-4943-afc9-b6754be640eb 0.0 0.0 0.0 0.0 0 No Lung Opacity / Not Normal 19.0 M AP
3 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 0.0 0.0 0.0 0.0 0 Normal 28.0 M PA
4 00436515-870c-4b36-a041-de91049b9ab4 264.0 152.0 213.0 379.0 1 Lung Opacity 32.0 F AP

Exploratory Data Analysis¶

In [ ]:
plt.figure(figsize=(7,4))
cmap = plt.get_cmap('Accent')
my_colors = [cmap(i) for i in np.linspace(0, 1, 8)]
g = sns.countplot(x = 'class', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of Class by Target');

Observations:

  • 'Normal class' or 'No Lung Opacity/Not Normal' are classified as Non-pneumonia cases.
  • Lung Opacity indicates Pneumonia cases which is less in comaprision with non-Pneumonia cases.
  • The number of 'No Lung Opacity/Not Normal' cases is pretty high which does not detect pneumonia but the patient needs more investigation further to find the root cause.
In [ ]:
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
g = final_df["class"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of Class');
plt.subplot(1,2,2)
g = final_df["PatientSex"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of Gender');

Observations:

  • Target class ratio having pneumonia to not having pneumonia is approx 30:70.
  • There is a data imbalance for the target class.
  • 43% of Patients are Females whereas 57% are Male patients.
  • Only Male/Female categories have been added. With evolving world, there needs to be more categories to accomocate LGBTQ+ at data entry level.
In [ ]:
fig = plt.figure(figsize=(10, 5))
plt.subplot(1,2,1)
g = sns.countplot(x = 'PatientSex', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of gender by Target');

plt.subplot(1, 2, 2)
g = sns.countplot(x = 'PatientSex', hue = 'class', data = final_df, palette = my_colors);
g.set_title('Distribution of gender by Class');

fig.tight_layout(pad=5.0)
plt.show();

Observations:

  • More number of males are getting the health check up done and so more cases of pneumonia detected in Male patients compared to females.
  • Does it mean that more health care facilities are available only to Male????
In [ ]:
fig = plt.figure(figsize=(14, 5))
plt.subplot(1,3, 1)
g = final_df["ViewPosition"].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Percentage Distribution of View Position');

plt.subplot(1,3, 2)
g = sns.countplot(x = 'ViewPosition', hue = 'Target', data = final_df, palette = my_colors);
g.set_title('Distribution of View Position with Target')

plt.subplot(1, 3, 3)
g = sns.countplot(x = 'ViewPosition', hue = 'class', data = final_df, palette = my_colors);
g.set_title('Distribution of View Position for various classes')

fig.tight_layout(pad=5.0)
plt.show();

Observations:

  • Two classes AP and PA observed for ViewPosition feature.
  • Equal distribution is noted in the dataset for ViewPosition feature.
  • More pneumonia cases are detected when the position is Anterior/Posterior (AP) compared to other (PA).
In [ ]:
final_df.info()
<class 'pandas.core.frame.DataFrame'>

RangeIndex: 30227 entries, 0 to 30226

Data columns (total 10 columns):

 #   Column        Non-Null Count  Dtype  

---  ------        --------------  -----  

 0   patientId     30227 non-null  object 

 1   x             30227 non-null  float64

 2   y             30227 non-null  float64

 3   width         30227 non-null  float64

 4   height        30227 non-null  float64

 5   Target        30227 non-null  int64  

 6   class         30227 non-null  object 

 7   PatientAge    30227 non-null  float64

 8   PatientSex    30227 non-null  object 

 9   ViewPosition  30227 non-null  object 

dtypes: float64(5), int64(1), object(4)

memory usage: 2.3+ MB

Convert all the variables to proper datatype¶

In [ ]:
final_df['PatientSex']   = final_df['PatientSex'].astype('category')
final_df['ViewPosition'] = final_df['ViewPosition'].astype('category')
final_df['Target']       = final_df['Target'].astype('category')
final_df['class']        = final_df['class'].astype('category')
final_df['PatientAge']   = final_df['PatientAge'].astype('int')
final_df['x']            = final_df['x'].astype('int')
final_df['y']            = final_df['y'].astype('int')
final_df['width']        = final_df['width'].astype('int')
final_df['height']       = final_df['height'].astype('int')
In [ ]:
plt.figure(figsize=(8,5))
g = sns.boxplot(x='class', y='PatientAge', data= final_df, palette = my_colors)
g.set_title('Distribution of Patient Age for various classes')
plt.show()

Observations:

  • Few outliers are seen in classes where pneumonia is not detected.
  • Outlier age is around 150 years which could be an error during data entry.
In [ ]:
final_df.describe(include = [np.number]).T
Out[ ]:
count mean std min 25% 50% 75% max
x 30227.0 124.561683 216.326397 0.0 0.0 0.0 193.0 835.0
y 30227.0 115.960962 190.012883 0.0 0.0 0.0 231.0 881.0
width 30227.0 69.060575 106.910496 0.0 0.0 0.0 169.0 528.0
height 30227.0 104.084825 176.932152 0.0 0.0 0.0 188.0 942.0
PatientAge 30227.0 46.797764 16.892940 1.0 34.0 49.0 59.0 155.0

Observations:

  • 50% of the patients are around 49 years old. The standard deviation is 16 which suggests that age is not normally distubuted.
  • The mean age is 46 years whereas minimum age is 1 year and the max age is 155 which seems to be an outlier.

Outlier Analysis¶

In [ ]:
# IQR
Q1 = np.percentile(final_df['PatientAge'], 25, method='midpoint')
Q3 = np.percentile(final_df['PatientAge'], 75, method='midpoint')
IQR = Q3 - Q1
upper=Q3+1.5*IQR
print(upper)
print(final_df[final_df['PatientAge']>90]['PatientAge'])
96.5

3921     148

8635      92

11032    151

17213    153

20185     91

20186     91

25357     92

26488    150

27746    155

29674     91

Name: PatientAge, dtype: int64

Display all entries greater than 90 years old

In [ ]:
final_df[final_df['PatientAge'] > 90]
Out[ ]:
patientId x y width height Target class PatientAge PatientSex ViewPosition
3921 3b8b8777-a1f6-4384-872a-28b95f59bf0d 0 0 0 0 0 Normal 148 M PA
8635 6108f7c0-96c4-48e6-994e-32e3cbeaf8d7 248 645 131 45 1 Lung Opacity 92 M AP
11032 73aeea88-fc48-4030-8564-0a9d7fdecac4 0 0 0 0 0 No Lung Opacity / Not Normal 151 F PA
17213 a4e8e96d-93a6-4251-b617-91382e610fab 0 0 0 0 0 No Lung Opacity / Not Normal 153 M PA
20185 b9a50c1f-4b93-4a91-963f-a8d06fe077ee 150 212 273 484 1 Lung Opacity 91 M PA
20186 b9a50c1f-4b93-4a91-963f-a8d06fe077ee 587 468 357 305 1 Lung Opacity 91 M PA
25357 e3314152-aa5f-4dff-93f8-93dc0bcbe57b 0 0 0 0 0 No Lung Opacity / Not Normal 92 M PA
26488 ec3697bd-184e-44ba-9688-ff8d5fbf9bbc 0 0 0 0 0 Normal 150 M PA
27746 f632328d-5819-4b29-b54f-adf4934bbee6 0 0 0 0 0 Normal 155 F PA
29674 2118026e-ed2f-4d1e-baa2-0e9e1004f72c 0 0 0 0 0 Normal 91 F PA

Observations:

  • PatientAge seems to be inaccurately mentioned for less than 0.1% of the records. Consider this to be some clerical error and thus will retain this data for our analysis as we do not want to lose valuable information for Lung opacity cases.

Distribution of Patient Age¶

In [ ]:
fig = plt.figure(figsize=(10, 4))

ax = fig.add_subplot(121)
g = sns.histplot(final_df['PatientAge'], color = 'orange')
g.set_title('Distribution of Patient Age');

ax = fig.add_subplot(122)
g = sns.histplot(final_df.loc[final_df['Target'] == 1, 'PatientAge'], color = 'turquoise')
g.set_title('Distribution of Patient Age having pneumonia');

Display images with bounding box¶

In [ ]:
from matplotlib.patches import Rectangle

def display_one_image(id, input_df):
    # Create a plot
    f, ax = plt.subplots(figsize=(5, 5))

    # Read the file for the given patientId
    data = pydicom.read_file(IMAGE_PATH + '%s.dcm' % id)

    # Display the image
    ax.imshow(data.pixel_array, cmap=plt.cm.bone)
    ax.set_title('ID: {}\n Age: {} Sex: {}'.format(id, data.PatientAge, data.PatientSex))

    # Copy all the rows where the patientId matches
    filter = input_df[input_df['patientId'] == id]

    # Collect data from all entries for a given patientId
    for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
      x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
      rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
      ax.add_patch(rectangle)


def display_image(input_df):
    img_data = list(input_df.T.to_dict().values())
    f, ax = plt.subplots(2,2, figsize=(12,15))

    # Iterate through all the entries
    for index, row in enumerate(img_data):
        # Read the file for the given patientId
        data = pydicom.read_file(IMAGE_PATH + '%s.dcm' % row['patientId'])

        # Display the image
        ax[index//2, index%2].imshow(data.pixel_array, cmap=plt.cm.bone)
        ax[index//2, index%2].set_title('ID: {}\n Age: {} Sex: {}'.format(row['patientId'], data.PatientAge, data.PatientSex))

        # Copy all the rows where the patientId matches
        filter = input_df[input_df['patientId'] == row['patientId']]

        # Collect data from all entries for a given patientId
        for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
          x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
          rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
          ax[index//2, index%2].add_patch(rectangle)

Patient Images having Pneumonia¶

In [ ]:
display_image(final_df[final_df['Target']==1].sample(n=4))

Patient Images Not having Pneumonia¶

In [ ]:
display_image(final_df[final_df['Target']==0].sample(n=4))
In [ ]:
no_of_bbox = final_df['patientId'].value_counts()
four_bbox_df = final_df[final_df.patientId.isin(no_of_bbox.index[no_of_bbox.gt(3)])]
four_bbox_df.sample()
Out[ ]:
patientId x y width height Target class PatientAge PatientSex ViewPosition
11441 76f71a93-8105-4c79-a010-0cfa86f0061a 673 303 106 145 1 Lung Opacity 43 M AP

Patient Images having Pneumonia with 4 bounding boxes¶

In [ ]:
sample_id = '76f71a93-8105-4c79-a010-0cfa86f0061a'
display_one_image(sample_id, four_bbox_df[four_bbox_df['patientId'] == sample_id])

Saving the feature engineered dataframe¶

In [ ]:
print('--'*40); print('Saving the feature engineered dataframe for future use'); print('--'*40)
final_df.to_pickle('/kaggle/working/train_data.pkl')
--------------------------------------------------------------------------------

Saving the feature engineered dataframe for future use

--------------------------------------------------------------------------------
In [ ]:
# Read `train_class_features.pkl` file, saved as EDA & Data Prep Module
final_df = pd.read_pickle('/kaggle/input/pneumonia-dataset/final_df.pkl')

For Image Classification problem, we do not intend to use other features.

Only Image will be our input to the model.

Since there is only one image per patient, drop the duplicates here.

In [ ]:
final_df_unique = final_df.drop_duplicates('patientId', keep='last')
In [ ]:
print('Shape of the Dataframe with Unique Patient IDs: ',final_df_unique.shape)
Shape of the Dataframe with Unique Patient IDs:  (26684, 10)
In [ ]:
## Checking the training data set with target distbution
ax = final_df_unique["Target"].value_counts().plot.bar(figsize=(6,4), title='Distribution of training data set with target',
                                                            rot = 0, color = 'turquoise');
plt.xlabel('Target')
plt.ylabel('No. of Patients')
for i in ax.containers:
    ax.bar_label(i,)

Number of cases with Target as 1 is around 6000. So we will consider this to be our sample size with Target grouped¶

In [ ]:
## Just taking a few samples from the dataset.
sample_data = final_df_unique.groupby('Target', group_keys=False).apply(lambda x: x.sample(6000))
In [ ]:
print('Shape of the Sample Dataframe to be input to model: ',sample_data.shape)
Shape of the Sample Dataframe to be input to model:  (12000, 10)
In [ ]:
ax = sample_data['Target'].value_counts().plot.bar(figsize=(5,4), title='Distribution of Sample dataset with target',
                                                            rot = 0, color = 'turquoise');
plt.xlabel('Target')
plt.ylabel('No. of Patients')
for i in ax.containers:
    ax.bar_label(i,)

Train Test Split¶

In [ ]:
train, test = train_test_split(sample_data, test_size=0.3 , random_state=42,stratify=sample_data['Target'])
test, val= train_test_split(test, test_size = 0.5, random_state=42,stratify=test['Target'])
In [ ]:
print('Shape of the Training Data   : ',train.shape)
print('Shape of the Validation Data : ',val.shape)
print('Shape of the Testing Data    : ',test.shape)
Shape of the Training Data   :  (8400, 10)

Shape of the Validation Data :  (1800, 10)

Shape of the Testing Data    :  (1800, 10)
In [ ]:
train.reset_index(inplace=True)
val.reset_index(inplace=True)
test.reset_index(inplace=True)
In [ ]:
plt.figure(figsize=(15,4))
plt.subplot(1,3,1)
g = train['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Train Dataset');
plt.subplot(1,3,2)
g = val['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Validation Dataset');
plt.subplot(1,3,3)
g = test['Target'].value_counts().plot(kind='pie',autopct='%1.0f%%', subplots=False, colors = my_colors);
g.set_title('Distribution of Target for Test Dataset');

Observations:

  • The train, test and validation data contain equally distributed Target 0 and 1 cases.
In [ ]:
def read_and_resize_images(final_df):
    resized_images = []
    boxes = []
    for i in range(len(final_df)):
        patient_id = final_df['patientId'][i]
        target = final_df['Target'][i]
        dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patient_id))
        img = dicom_data.pixel_array

        #Resize image to 32X32
        img = cv2.resize(img, (32, 32))
        # add trailing channel dimension
        img = np.expand_dims(img, -1)

        resized_images.append(img)
        boxes.append(np.array(target, dtype=np.float32))
    return np.array(resized_images), np.array(boxes)
In [ ]:
# Read and resize training, validation and test images
X_train, y_train = read_and_resize_images(train)
X_val, y_val = read_and_resize_images(val)
X_test, y_test = read_and_resize_images(test)

Normalize the data¶

In [ ]:
X_train = np.array(X_train) / 255
X_val = np.array(X_val) / 255
X_test = np.array(X_test) / 255

Check Shape of train, test and validation data¶

In [ ]:
# Checking the shape of train, test and validation sets
print('Shape of Training Data   X: ', X_train.shape,'Y: ',y_train.shape )
print('Shape of Testing  Data   X: ', X_test.shape,'Y: ' , y_test.shape)
print('Shape of Validation Data X: ', X_val.shape,'Y: ',y_val.shape)
Shape of Training Data   X:  (8400, 32, 32, 1) Y:  (8400,)

Shape of Testing  Data   X:  (1800, 32, 32, 1) Y:  (1800,)

Shape of Validation Data X:  (1800, 32, 32, 1) Y:  (1800,)
In [ ]:
def save_pickle(dest, filename):
    file = open(filename, 'wb')
    # Pickle dictionary using protocol 0.
    pickle.dump(dest, file)
    file.close()

save_pickle(X_train, '/kaggle/working/X_train_data.pkl')
save_pickle(X_val, '/kaggle/working/X_val_data.pkl')
save_pickle(X_test, '/kaggle/working/X_test_data.pkl')
save_pickle(y_train, '/kaggle/working/y_train_data.pkl')
save_pickle(y_val, '/kaggle/working/y_val_data.pkl')
save_pickle(y_test, '/kaggle/working/y_test_data.pkl')
In [ ]:
def open_pickle(filename):
    file = open(filename, 'rb')
    data = pickle.load(file)
    file.close()
    return data

X_train = open_pickle('/kaggle/working/X_train_data.pkl')
X_val = open_pickle('/kaggle/working/X_val_data.pkl')
X_test = open_pickle('/kaggle/working/X_test_data.pkl')
y_train = open_pickle('/kaggle/working/y_train_data.pkl')
y_val = open_pickle('/kaggle/working/y_val_data.pkl')
y_test = open_pickle('/kaggle/working/y_test_data.pkl')

Data Augmentation¶

Existing dataset can be modified and more samples can be created for training purpose which will help to avoid overfitting problem. The idea is to alter the training data with small transformations to reproduce the variations. Approaches that alter the training data in ways that change the array representation while keeping the label the same are known as data augmentation techniques. Commonly used techniques are grayscales, horizontal flips, vertical flips, random crops, color jitters, translations, rotations,etc.

Below parameters have been chosen for the data augmentation:

  • Randomly rotate some training images by 30 degrees
  • Randomly Zoom by 20% some training images
  • Randomly shift images horizontally by 10% of the width
  • Randomly shift images vertically by 10% of the height
  • Randomly flip images horizontally.

Once our model is ready, we fit the training dataset.

In [ ]:
batch_size = 8
# Establish our metrics
METRICS = ['acc',
           tf.keras.metrics.Precision(name='precision'),
           tf.keras.metrics.Recall(name='recall')]

learning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', patience = 2, verbose=1,factor=0.3, min_lr=0.000001)

early_stopping = EarlyStopping(monitor='val_loss',patience=5, restore_best_weights=True)

# Callbacks to reduce learning rate timely after monitoring a quantit
filepath="/kaggle/working/weights.hdf5"

checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')

train_datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range = 30,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.2, # Randomly zoom image
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip = True,  # randomly flip images
        vertical_flip=False)  # randomly flip images

train_datagen.fit(X_train)

test_datagen = ImageDataGenerator()

train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)

valid_generator = train_datagen.flow(X_val, y_val, batch_size=batch_size)

test_generator = test_datagen.flow(X_test, y_test, batch_size=1)

def fit_model(model):
    history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
                        validation_data = valid_generator,
                        callbacks=[checkpoint,early_stopping,learning_rate_reduction],
                        batch_size=batch_size ,use_multiprocessing=True)
    return history

Model Building¶

Model 1 - Basic CNN Model

  • The basic model contains 3 Convolution Layers(Filters: 32, 64, 32) with few Dense layers having activation function as ReLu
  • Max Pooling with pool size (2,2) has been added between layers
  • Sigmoid function is used at the output layer for binary classification.
  • Optimiser Used : RMSProp

Model 2 - CNN Model with Batch Normalization

  • The basic model contains 3 Convolution Layers(Filters: 32, 64, 32) with few Dense layers having activation function as ReLu
  • Batch Normalization and Max Pooling with pool size (2,2) has been added between layers
  • Sigmoid function is used at the output layer for binary classification.
  • Optimiser Used : RMSProp

Model 3 - CNN Model with Leaky ReLU

  • The basic model contains 3 Convolution Layers(Filters: 32, 64, 128) with Dense layers having activation function as Leaky ReLu
  • Max Pooling with pool size (2,2) has been added between layers
  • Sigmoid function is used at the output layer for binary classification.
  • Optimiser Used : Adam

Model 4 - CNN Model with Adam Optimizer

  • The basic model contains 3 Convolution Layers(Filters: 32, 64, 128) with few Dense layers having activation function as ReLu
  • Max Pooling with pool size (2,2) has been added between layers
  • Sigmoid function is used at the output layer for binary classification.
  • Optimiser Used : Adam

Since the problem statement is for binary classification, the below three metrics are being used for performance measurement. Accuracy, Precision, Recall

In [ ]:
# Basic CNN Model
def create_model_1():
    model = Sequential()
    model.add(Conv2D(filters=32, kernel_size=3, activation='relu', input_shape = (32,32,1)))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=64, kernel_size=3, activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=32, kernel_size=3, activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Flatten())
    model.add(Dense(activation='relu', units=128))
    model.add(Dense(activation='sigmoid', units=1))
    model.compile(optimizer = "rmsprop" , loss = 'binary_crossentropy' , metrics = METRICS)
    model.summary()
    return model
In [ ]:
# Basic CNN Model with Batch Normalization
def create_model_2():
    model = Sequential()
    model.add(Conv2D(filters=32, kernel_size=3, activation='relu', input_shape = (32,32,1)))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=64, kernel_size=3, activation='relu'))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Conv2D(filters=32, kernel_size=3, activation='relu'))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Flatten())
    model.add(Dense(activation='relu', units=128))
    model.add(Dense(activation='sigmoid', units=1))
    model.compile(optimizer = "rmsprop" , loss = 'binary_crossentropy' , metrics = METRICS)
    model.summary()
    return model
In [ ]:
# Basic CNN Model with Leaky ReLU
def create_model_3():
    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation=LeakyReLU(alpha=0.1), input_shape=(32, 32, 1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(64, (3, 3), activation=LeakyReLU(alpha=0.1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(128, (3, 3), activation=LeakyReLU(alpha=0.1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(512, activation=LeakyReLU(alpha=0.1)))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
    model.summary()
    return model
In [ ]:
# Basic CNN Model with Adam as Optimizer
def create_model_4():
    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(128, (3, 3), activation='relu'))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(512, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics = METRICS)
    model.summary()
    return model

Performance Metrics Output¶

Create a function that displays the performance metrics of the model. Metrics: Accuracy, Loss, ROC Curve, Classification Matrix Charts:

  • Train VS. Validation Accuracy
  • Train VS. Validation Loss
  • Confusion Matrix
  • ROC Curve
  • Real Labels vs Predicted Labels
In [ ]:
model_comparision_list = []
In [ ]:
def get_model_prediction(model):
    # Predict the values from the validation dataset
    predictions = model.predict(X_test)
    # Convert predictions classes to one hot vectors
    return predictions.round().astype(int).tolist()
In [ ]:
NUM_OF_EPOCHS = 12
FONT_SIZE = 10

def evaluate_model_perf(history, model, model_descr):
    epochs = [i for i in range(len(history.history['acc']))]  # Use the number of epochs actually trained
    fig = plt.figure(figsize=(16,5 ))

    plt.subplot(1,3,1)
    plt.plot(epochs , history.history['acc'] , marker = 'o' ,color = 'orange', label = 'Training Accuracy')
    plt.plot(epochs , history.history['val_acc'] ,  marker = 'o' ,color = 'turquoise', label = 'Validation Accuracy')
    plt.title('Training & Validation Accuracy')
    plt.legend(fontsize=FONT_SIZE)
    plt.xticks(fontsize=FONT_SIZE)
    plt.yticks(fontsize=FONT_SIZE)
    plt.xlabel("Epochs", size=FONT_SIZE)
    plt.ylabel("Accuracy", size=FONT_SIZE)

    plt.subplot(1,3,2)
    plt.plot(epochs , history.history['loss'] ,  marker = 'o' ,color = 'orange', label = 'Training Loss')
    plt.plot(epochs , history.history['val_loss'] , marker = 'o' ,color = 'turquoise' , label = 'Validation Loss')
    plt.title('Testing Accuracy & Loss')
    plt.xticks(fontsize=FONT_SIZE)
    plt.yticks(fontsize=FONT_SIZE)
    plt.legend(fontsize=FONT_SIZE)
    plt.xlabel("Epochs", size=FONT_SIZE)
    plt.ylabel("Training & Validation Loss", size=FONT_SIZE)

    # Calculate y_pred based on the validation set
    y_pred = get_model_prediction(model)

    ## CONFUSION MATRIX
    plt.subplot(1,3,3)
    # Set up the labels for the confusion matrix
    cm = confusion_matrix(y_test, y_pred)
    labels = ['NORMAL', 'PNEUMONIA']
    ax = sns.heatmap(cm,  annot=True, fmt='d', cmap="GnBu", annot_kws={"fontsize": FONT_SIZE},
                    xticklabels = labels, yticklabels = labels)
    ax.set(ylabel="True Label", xlabel="Predicted Label")
    plt.title('Confusion Matrix')
    plt.show()
    plt.tight_layout()

    print('\n\n\n')
    print('--' * 40)
    print("Classification Matrix")
    print('--' * 40)
    print(classification_report(y_test, y_pred,
                                target_names=['Normal (Class 0)', 'Pneumonia (Class 1)']))
    print('--' * 40)

    # performance_matrix list of this model
    performance_matrix = []
    performance_matrix.append(model_descr)
    performance_matrix.append(accuracy_score(y_test, y_pred) * 100)
    performance_matrix.append(precision_score(y_test, y_pred, average='macro') * 100)
    performance_matrix.append(recall_score(y_test, y_pred, average='macro') * 100)
    performance_matrix.append(f1_score(y_test, y_pred, average='macro') * 100)
    # Store the performance per model

    model_comparision_list.append(performance_matrix)
In [ ]:
def display_ROC_comparision():
    fig = plt.figure(figsize=(14,8))

    y_pred_model_1 = get_model_prediction(model_1)
    y_pred_model_2 = get_model_prediction(model_2)
    y_pred_model_3 = get_model_prediction(model_3)
    y_pred_model_4 = get_model_prediction(model_4)


    ## ROC CURVE
    plt.subplot(2,2,3)
    plt.title('ROC Curve for all models')
    plt.plot([0, 1], [0, 1], 'k--', label = "Random (AUC = 50%)")
    fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_1)
    auc_model = roc_auc_score(y_test, y_pred_model_1)
    plt.plot(fpr, tpr, label='Model 1 (AUC = {:.2f}%)'.format(auc_model*100))
    fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_2)
    auc_model = roc_auc_score(y_test, y_pred_model_2)
    plt.plot(fpr, tpr, label='Model 2 (AUC = {:.2f}%)'.format(auc_model*100))
    fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_3)
    auc_model = roc_auc_score(y_test, y_pred_model_3)
    plt.plot(fpr, tpr, label='Model 3 (AUC = {:.2f}%)'.format(auc_model*100))
    fpr, tpr, thresholds = roc_curve(y_test, y_pred_model_4)
    auc_model = roc_auc_score(y_test, y_pred_model_4)
    plt.plot(fpr, tpr, label='Model 4 (AUC = {:.2f}%)'.format(auc_model*100))
    plt.xticks(fontsize=FONT_SIZE)
    plt.yticks(fontsize=FONT_SIZE)
    plt.xlabel('False Positive Rate', size=FONT_SIZE)
    plt.ylabel('True Positive Rate', size=FONT_SIZE)
    plt.legend(loc='best', fontsize=FONT_SIZE)
In [ ]:
def display_model_matrix():
  final_perf_df = pd.DataFrame(model_comparision_list, columns=['Model','Accuracy','Precision','Recall','F1 Score'])
  final_perf_df.sort_values(by=['Accuracy'], inplace=True, ascending=False)

  print('\n')
  print('-'*80)
  print("Model Performance Comparision Matrix")
  print('-'*80)
  print(final_perf_df)
  print('-'*80)
In [ ]:
model_1 = create_model_1()
history_1 = fit_model(model_1)
evaluate_model_perf(history_1, model_1, 'Basic_CNN_Model')
save_pickle(model_1, '/kaggle/working/model_1.pkl')
Model: "sequential_3"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_9 (Conv2D)           (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_9 (MaxPooling  (None, 15, 15, 32)       0         

 2D)                                                             

                                                                 

 conv2d_10 (Conv2D)          (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_10 (MaxPoolin  (None, 6, 6, 64)         0         

 g2D)                                                            

                                                                 

 conv2d_11 (Conv2D)          (None, 4, 4, 32)          18464     

                                                                 

 max_pooling2d_11 (MaxPoolin  (None, 2, 2, 32)         0         

 g2D)                                                            

                                                                 

 flatten_3 (Flatten)         (None, 128)               0         

                                                                 

 dense_6 (Dense)             (None, 128)               16512     

                                                                 

 dense_7 (Dense)             (None, 1)                 129       

                                                                 

=================================================================

Total params: 53,921

Trainable params: 53,921

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.6092 - acc: 0.6621 - precision: 0.6686 - recall: 0.6854

Epoch 1: val_acc did not improve from 0.72167

1050/1050 [==============================] - 17s 15ms/step - loss: 0.6088 - acc: 0.6619 - precision: 0.6681 - recall: 0.6847 - val_loss: 0.5716 - val_acc: 0.7028 - val_precision: 0.7044 - val_recall: 0.6989 - lr: 0.0010

Epoch 2/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5720 - acc: 0.7020 - precision: 0.7003 - recall: 0.7064

Epoch 2: val_acc improved from 0.72167 to 0.72833, saving model to /kaggle/working/weights.hdf5

1050/1050 [==============================] - 16s 16ms/step - loss: 0.5720 - acc: 0.7020 - precision: 0.7003 - recall: 0.7064 - val_loss: 0.5501 - val_acc: 0.7283 - val_precision: 0.7134 - val_recall: 0.7633 - lr: 0.0010

Epoch 3/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5656 - acc: 0.7095 - precision: 0.7074 - recall: 0.7148

Epoch 3: val_acc did not improve from 0.72833

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5656 - acc: 0.7095 - precision: 0.7074 - recall: 0.7148 - val_loss: 0.5454 - val_acc: 0.7183 - val_precision: 0.7102 - val_recall: 0.7378 - lr: 0.0010

Epoch 4/12

1041/1050 [============================>.] - ETA: 0s - loss: 0.5578 - acc: 0.7242 - precision: 0.7234 - recall: 0.7250

Epoch 4: val_acc did not improve from 0.72833

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5583 - acc: 0.7240 - precision: 0.7237 - recall: 0.7248 - val_loss: 0.5521 - val_acc: 0.7178 - val_precision: 0.6870 - val_recall: 0.8000 - lr: 0.0010

Epoch 5/12

1042/1050 [============================>.] - ETA: 0s - loss: 0.5567 - acc: 0.7174 - precision: 0.7164 - recall: 0.7188

Epoch 5: val_acc did not improve from 0.72833

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5561 - acc: 0.7179 - precision: 0.7173 - recall: 0.7190 - val_loss: 0.5567 - val_acc: 0.7178 - val_precision: 0.6747 - val_recall: 0.8411 - lr: 0.0010

Epoch 6/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5504 - acc: 0.7263 - precision: 0.7260 - recall: 0.7269

Epoch 6: val_acc improved from 0.72833 to 0.73111, saving model to /kaggle/working/weights.hdf5

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5504 - acc: 0.7263 - precision: 0.7260 - recall: 0.7269 - val_loss: 0.5458 - val_acc: 0.7311 - val_precision: 0.7470 - val_recall: 0.6989 - lr: 0.0010

Epoch 7/12

1046/1050 [============================>.] - ETA: 0s - loss: 0.5509 - acc: 0.7272 - precision: 0.7290 - recall: 0.7243

Epoch 7: val_acc did not improve from 0.73111

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5505 - acc: 0.7275 - precision: 0.7288 - recall: 0.7248 - val_loss: 0.5700 - val_acc: 0.7089 - val_precision: 0.8003 - val_recall: 0.5567 - lr: 0.0010

Epoch 8/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5493 - acc: 0.7253 - precision: 0.7254 - recall: 0.7247

Epoch 8: val_acc did not improve from 0.73111

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5491 - acc: 0.7252 - precision: 0.7256 - recall: 0.7245 - val_loss: 0.5485 - val_acc: 0.7228 - val_precision: 0.7750 - val_recall: 0.6278 - lr: 0.0010

57/57 [==============================] - 0s 2ms/step







--------------------------------------------------------------------------------

Classification Matrix

--------------------------------------------------------------------------------

                     precision    recall  f1-score   support



   Normal (Class 0)       0.73      0.76      0.75       900

Pneumonia (Class 1)       0.75      0.72      0.73       900



           accuracy                           0.74      1800

          macro avg       0.74      0.74      0.74      1800

       weighted avg       0.74      0.74      0.74      1800



--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
In [ ]:
model_2 = create_model_2()
history_2 = fit_model(model_2)
evaluate_model_perf(history_2, model_2, 'CNN Model_Batch_Norm')
save_pickle(model_2, '/kaggle/working/model_2.pkl')
Model: "sequential_4"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_12 (Conv2D)          (None, 30, 30, 32)        320       

                                                                 

 batch_normalization (BatchN  (None, 30, 30, 32)       128       

 ormalization)                                                   

                                                                 

 max_pooling2d_12 (MaxPoolin  (None, 15, 15, 32)       0         

 g2D)                                                            

                                                                 

 conv2d_13 (Conv2D)          (None, 13, 13, 64)        18496     

                                                                 

 batch_normalization_1 (Batc  (None, 13, 13, 64)       256       

 hNormalization)                                                 

                                                                 

 max_pooling2d_13 (MaxPoolin  (None, 6, 6, 64)         0         

 g2D)                                                            

                                                                 

 conv2d_14 (Conv2D)          (None, 4, 4, 32)          18464     

                                                                 

 batch_normalization_2 (Batc  (None, 4, 4, 32)         128       

 hNormalization)                                                 

                                                                 

 max_pooling2d_14 (MaxPoolin  (None, 2, 2, 32)         0         

 g2D)                                                            

                                                                 

 flatten_4 (Flatten)         (None, 128)               0         

                                                                 

 dense_8 (Dense)             (None, 128)               16512     

                                                                 

 dense_9 (Dense)             (None, 1)                 129       

                                                                 

=================================================================

Total params: 54,433

Trainable params: 54,177

Non-trainable params: 256

_________________________________________________________________

Epoch 1/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.6009 - acc: 0.6916 - precision: 0.7054 - recall: 0.6778

Epoch 1: val_acc did not improve from 0.73111

1050/1050 [==============================] - 20s 17ms/step - loss: 0.6007 - acc: 0.6918 - precision: 0.7052 - recall: 0.6778 - val_loss: 0.5711 - val_acc: 0.7089 - val_precision: 0.7582 - val_recall: 0.6133 - lr: 0.0010

Epoch 2/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5721 - acc: 0.7178 - precision: 0.7221 - recall: 0.7083

Epoch 2: val_acc did not improve from 0.73111

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5721 - acc: 0.7179 - precision: 0.7221 - recall: 0.7083 - val_loss: 0.5589 - val_acc: 0.7128 - val_precision: 0.6944 - val_recall: 0.7600 - lr: 0.0010

Epoch 3/12

1042/1050 [============================>.] - ETA: 0s - loss: 0.5623 - acc: 0.7216 - precision: 0.7255 - recall: 0.7131

Epoch 3: val_acc did not improve from 0.73111

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5624 - acc: 0.7218 - precision: 0.7255 - recall: 0.7136 - val_loss: 0.5634 - val_acc: 0.7172 - val_precision: 0.7005 - val_recall: 0.7589 - lr: 0.0010

Epoch 4/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5557 - acc: 0.7297 - precision: 0.7287 - recall: 0.7318

Epoch 4: val_acc did not improve from 0.73111

1050/1050 [==============================] - 18s 17ms/step - loss: 0.5560 - acc: 0.7294 - precision: 0.7286 - recall: 0.7312 - val_loss: 0.5770 - val_acc: 0.7117 - val_precision: 0.8029 - val_recall: 0.5611 - lr: 0.0010

Epoch 5/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5484 - acc: 0.7352 - precision: 0.7348 - recall: 0.7358

Epoch 5: val_acc did not improve from 0.73111

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5484 - acc: 0.7352 - precision: 0.7350 - recall: 0.7357 - val_loss: 0.5583 - val_acc: 0.7089 - val_precision: 0.7094 - val_recall: 0.7078 - lr: 0.0010

Epoch 6/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5418 - acc: 0.7407 - precision: 0.7369 - recall: 0.7486

Epoch 6: val_acc did not improve from 0.73111

1050/1050 [==============================] - 18s 17ms/step - loss: 0.5430 - acc: 0.7396 - precision: 0.7355 - recall: 0.7483 - val_loss: 1.5557 - val_acc: 0.5017 - val_precision: 0.8000 - val_recall: 0.0044 - lr: 0.0010

Epoch 7/12

1041/1050 [============================>.] - ETA: 0s - loss: 0.5486 - acc: 0.7423 - precision: 0.7408 - recall: 0.7451

Epoch 7: val_acc did not improve from 0.73111

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5476 - acc: 0.7425 - precision: 0.7413 - recall: 0.7450 - val_loss: 0.5467 - val_acc: 0.7272 - val_precision: 0.7055 - val_recall: 0.7800 - lr: 0.0010

Epoch 8/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5413 - acc: 0.7351 - precision: 0.7321 - recall: 0.7417

Epoch 8: val_acc did not improve from 0.73111

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5414 - acc: 0.7350 - precision: 0.7319 - recall: 0.7417 - val_loss: 0.5710 - val_acc: 0.7122 - val_precision: 0.7736 - val_recall: 0.6000 - lr: 0.0010

Epoch 9/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5405 - acc: 0.7382 - precision: 0.7406 - recall: 0.7333

Epoch 9: val_acc improved from 0.73111 to 0.73722, saving model to /kaggle/working/weights.hdf5

1050/1050 [==============================] - 17s 17ms/step - loss: 0.5404 - acc: 0.7382 - precision: 0.7407 - recall: 0.7331 - val_loss: 0.5415 - val_acc: 0.7372 - val_precision: 0.7755 - val_recall: 0.6678 - lr: 0.0010

Epoch 10/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5413 - acc: 0.7424 - precision: 0.7402 - recall: 0.7465

Epoch 10: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5409 - acc: 0.7426 - precision: 0.7407 - recall: 0.7467 - val_loss: 0.5588 - val_acc: 0.7056 - val_precision: 0.6719 - val_recall: 0.8033 - lr: 0.0010

Epoch 11/12

1046/1050 [============================>.] - ETA: 0s - loss: 0.5371 - acc: 0.7439 - precision: 0.7437 - recall: 0.7435

Epoch 11: val_acc did not improve from 0.73722

1050/1050 [==============================] - 18s 17ms/step - loss: 0.5371 - acc: 0.7436 - precision: 0.7438 - recall: 0.7431 - val_loss: 0.5641 - val_acc: 0.7156 - val_precision: 0.6628 - val_recall: 0.8778 - lr: 0.0010

Epoch 12/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.5356 - acc: 0.7440 - precision: 0.7432 - recall: 0.7461

Epoch 12: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5349 - acc: 0.7446 - precision: 0.7439 - recall: 0.7462 - val_loss: 0.5456 - val_acc: 0.7239 - val_precision: 0.7114 - val_recall: 0.7533 - lr: 0.0010

57/57 [==============================] - 0s 3ms/step







--------------------------------------------------------------------------------

Classification Matrix

--------------------------------------------------------------------------------

                     precision    recall  f1-score   support



   Normal (Class 0)       0.76      0.65      0.70       900

Pneumonia (Class 1)       0.70      0.79      0.74       900



           accuracy                           0.72      1800

          macro avg       0.73      0.72      0.72      1800

       weighted avg       0.73      0.72      0.72      1800



--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
In [ ]:
model_3 = create_model_3()
history_3 = fit_model(model_3)
evaluate_model_perf(history_3, model_3, 'CNN_Leaky_ReLU')
save_pickle(model_3, '/kaggle/working/model_3.pkl')
Model: "sequential_5"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_15 (Conv2D)          (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_15 (MaxPoolin  (None, 15, 15, 32)       0         

 g2D)                                                            

                                                                 

 conv2d_16 (Conv2D)          (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_16 (MaxPoolin  (None, 6, 6, 64)         0         

 g2D)                                                            

                                                                 

 conv2d_17 (Conv2D)          (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_17 (MaxPoolin  (None, 2, 2, 128)        0         

 g2D)                                                            

                                                                 

 flatten_5 (Flatten)         (None, 512)               0         

                                                                 

 dense_10 (Dense)            (None, 512)               262656    

                                                                 

 dropout (Dropout)           (None, 512)               0         

                                                                 

 dense_11 (Dense)            (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

1044/1050 [============================>.] - ETA: 0s - loss: 0.6046 - acc: 0.6709 - precision: 0.6759 - recall: 0.6935

Epoch 1: val_acc did not improve from 0.73722

1050/1050 [==============================] - 20s 16ms/step - loss: 0.6048 - acc: 0.6710 - precision: 0.6754 - recall: 0.6943 - val_loss: 0.5731 - val_acc: 0.7161 - val_precision: 0.6975 - val_recall: 0.7633 - lr: 0.0010

Epoch 2/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5732 - acc: 0.7040 - precision: 0.7038 - recall: 0.7048

Epoch 2: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5734 - acc: 0.7037 - precision: 0.7035 - recall: 0.7040 - val_loss: 0.5586 - val_acc: 0.7150 - val_precision: 0.7268 - val_recall: 0.6889 - lr: 0.0010

Epoch 3/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5658 - acc: 0.7081 - precision: 0.7094 - recall: 0.7036

Epoch 3: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5657 - acc: 0.7077 - precision: 0.7096 - recall: 0.7033 - val_loss: 0.5470 - val_acc: 0.7233 - val_precision: 0.7228 - val_recall: 0.7244 - lr: 0.0010

Epoch 4/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.5586 - acc: 0.7222 - precision: 0.7247 - recall: 0.7174

Epoch 4: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5584 - acc: 0.7226 - precision: 0.7247 - recall: 0.7181 - val_loss: 0.5560 - val_acc: 0.7206 - val_precision: 0.7436 - val_recall: 0.6733 - lr: 0.0010

Epoch 5/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5578 - acc: 0.7207 - precision: 0.7198 - recall: 0.7229

Epoch 5: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5578 - acc: 0.7207 - precision: 0.7198 - recall: 0.7229 - val_loss: 0.5414 - val_acc: 0.7272 - val_precision: 0.7485 - val_recall: 0.6844 - lr: 0.0010

Epoch 6/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.5597 - acc: 0.7206 - precision: 0.7255 - recall: 0.7106

Epoch 6: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5597 - acc: 0.7207 - precision: 0.7250 - recall: 0.7112 - val_loss: 0.5588 - val_acc: 0.7172 - val_precision: 0.6809 - val_recall: 0.8178 - lr: 0.0010

Epoch 7/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5526 - acc: 0.7228 - precision: 0.7251 - recall: 0.7175

Epoch 7: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5531 - acc: 0.7226 - precision: 0.7250 - recall: 0.7174 - val_loss: 0.5625 - val_acc: 0.7211 - val_precision: 0.7704 - val_recall: 0.6300 - lr: 0.0010

Epoch 8/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5555 - acc: 0.7252 - precision: 0.7236 - recall: 0.7287

Epoch 8: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5555 - acc: 0.7251 - precision: 0.7236 - recall: 0.7286 - val_loss: 0.5569 - val_acc: 0.7222 - val_precision: 0.7762 - val_recall: 0.6244 - lr: 0.0010

Epoch 9/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5466 - acc: 0.7266 - precision: 0.7256 - recall: 0.7297

Epoch 9: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5468 - acc: 0.7264 - precision: 0.7248 - recall: 0.7300 - val_loss: 0.5464 - val_acc: 0.7289 - val_precision: 0.6969 - val_recall: 0.8100 - lr: 0.0010

Epoch 10/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5474 - acc: 0.7307 - precision: 0.7311 - recall: 0.7300

Epoch 10: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5472 - acc: 0.7307 - precision: 0.7312 - recall: 0.7298 - val_loss: 0.5607 - val_acc: 0.7117 - val_precision: 0.7900 - val_recall: 0.5767 - lr: 0.0010

57/57 [==============================] - 0s 2ms/step







--------------------------------------------------------------------------------

Classification Matrix

--------------------------------------------------------------------------------

                     precision    recall  f1-score   support



   Normal (Class 0)       0.71      0.82      0.76       900

Pneumonia (Class 1)       0.79      0.67      0.72       900



           accuracy                           0.74      1800

          macro avg       0.75      0.74      0.74      1800

       weighted avg       0.75      0.74      0.74      1800



--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
In [ ]:
model_4 = create_model_4()
history_4 = fit_model(model_4)
evaluate_model_perf(history_4, model_4, 'CNN_Adam_Opt')
save_pickle(model_4, '/kaggle/working/model_4.pkl')
Model: "sequential_6"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_18 (Conv2D)          (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_18 (MaxPoolin  (None, 15, 15, 32)       0         

 g2D)                                                            

                                                                 

 conv2d_19 (Conv2D)          (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_19 (MaxPoolin  (None, 6, 6, 64)         0         

 g2D)                                                            

                                                                 

 conv2d_20 (Conv2D)          (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_20 (MaxPoolin  (None, 2, 2, 128)        0         

 g2D)                                                            

                                                                 

 flatten_6 (Flatten)         (None, 512)               0         

                                                                 

 dense_12 (Dense)            (None, 512)               262656    

                                                                 

 dropout_1 (Dropout)         (None, 512)               0         

                                                                 

 dense_13 (Dense)            (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.6045 - acc: 0.6739 - precision: 0.6925 - recall: 0.6493

Epoch 1: val_acc did not improve from 0.73722

1050/1050 [==============================] - 19s 15ms/step - loss: 0.6048 - acc: 0.6736 - precision: 0.6922 - recall: 0.6492 - val_loss: 0.5612 - val_acc: 0.7128 - val_precision: 0.7189 - val_recall: 0.6989 - lr: 0.0010

Epoch 2/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5714 - acc: 0.7084 - precision: 0.7086 - recall: 0.7077

Epoch 2: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5712 - acc: 0.7087 - precision: 0.7089 - recall: 0.7081 - val_loss: 0.5638 - val_acc: 0.7172 - val_precision: 0.6885 - val_recall: 0.7933 - lr: 0.0010

Epoch 3/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5627 - acc: 0.7150 - precision: 0.7145 - recall: 0.7162

Epoch 3: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5627 - acc: 0.7149 - precision: 0.7144 - recall: 0.7160 - val_loss: 0.6955 - val_acc: 0.6478 - val_precision: 0.7969 - val_recall: 0.3967 - lr: 0.0010

Epoch 4/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5653 - acc: 0.7096 - precision: 0.7131 - recall: 0.7013

Epoch 4: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5661 - acc: 0.7094 - precision: 0.7132 - recall: 0.7005 - val_loss: 0.5536 - val_acc: 0.7228 - val_precision: 0.7424 - val_recall: 0.6822 - lr: 0.0010

Epoch 5/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5578 - acc: 0.7216 - precision: 0.7203 - recall: 0.7244

Epoch 5: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5578 - acc: 0.7215 - precision: 0.7202 - recall: 0.7245 - val_loss: 0.5473 - val_acc: 0.7294 - val_precision: 0.7209 - val_recall: 0.7489 - lr: 0.0010

Epoch 6/12

1046/1050 [============================>.] - ETA: 0s - loss: 0.5551 - acc: 0.7216 - precision: 0.7241 - recall: 0.7148

Epoch 6: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5555 - acc: 0.7208 - precision: 0.7242 - recall: 0.7133 - val_loss: 0.5571 - val_acc: 0.7206 - val_precision: 0.7701 - val_recall: 0.6289 - lr: 0.0010

Epoch 7/12

1042/1050 [============================>.] - ETA: 0s - loss: 0.5521 - acc: 0.7234 - precision: 0.7255 - recall: 0.7186

Epoch 7: val_acc did not improve from 0.73722

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5524 - acc: 0.7230 - precision: 0.7247 - recall: 0.7190 - val_loss: 0.5483 - val_acc: 0.7217 - val_precision: 0.7239 - val_recall: 0.7167 - lr: 0.0010

Epoch 8/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5475 - acc: 0.7270 - precision: 0.7237 - recall: 0.7345

Epoch 8: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5473 - acc: 0.7270 - precision: 0.7238 - recall: 0.7343 - val_loss: 0.5560 - val_acc: 0.7139 - val_precision: 0.7556 - val_recall: 0.6322 - lr: 0.0010

Epoch 9/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5481 - acc: 0.7299 - precision: 0.7295 - recall: 0.7307

Epoch 9: val_acc did not improve from 0.73722

1050/1050 [==============================] - 16s 16ms/step - loss: 0.5480 - acc: 0.7300 - precision: 0.7297 - recall: 0.7307 - val_loss: 0.5425 - val_acc: 0.7306 - val_precision: 0.7150 - val_recall: 0.7667 - lr: 0.0010

Epoch 10/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5467 - acc: 0.7281 - precision: 0.7303 - recall: 0.7233

Epoch 10: val_acc improved from 0.73722 to 0.74167, saving model to /kaggle/working/weights.hdf5

1050/1050 [==============================] - 17s 16ms/step - loss: 0.5467 - acc: 0.7281 - precision: 0.7303 - recall: 0.7233 - val_loss: 0.5303 - val_acc: 0.7417 - val_precision: 0.7574 - val_recall: 0.7111 - lr: 0.0010

Epoch 11/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5441 - acc: 0.7315 - precision: 0.7310 - recall: 0.7309

Epoch 11: val_acc did not improve from 0.74167

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5438 - acc: 0.7317 - precision: 0.7320 - recall: 0.7310 - val_loss: 0.5467 - val_acc: 0.7367 - val_precision: 0.7710 - val_recall: 0.6733 - lr: 0.0010

Epoch 12/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.5395 - acc: 0.7303 - precision: 0.7292 - recall: 0.7328

Epoch 12: val_acc improved from 0.74167 to 0.74333, saving model to /kaggle/working/weights.hdf5

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5394 - acc: 0.7305 - precision: 0.7293 - recall: 0.7331 - val_loss: 0.5387 - val_acc: 0.7433 - val_precision: 0.7355 - val_recall: 0.7600 - lr: 0.0010

57/57 [==============================] - 0s 2ms/step







--------------------------------------------------------------------------------

Classification Matrix

--------------------------------------------------------------------------------

                     precision    recall  f1-score   support



   Normal (Class 0)       0.76      0.75      0.75       900

Pneumonia (Class 1)       0.75      0.76      0.76       900



           accuracy                           0.75      1800

          macro avg       0.75      0.75      0.75      1800

       weighted avg       0.75      0.75      0.75      1800



--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
In [ ]:
display_ROC_comparision()
57/57 [==============================] - 0s 2ms/step

57/57 [==============================] - 0s 2ms/step

57/57 [==============================] - 0s 2ms/step

57/57 [==============================] - 0s 2ms/step
In [ ]:
display_model_matrix()



--------------------------------------------------------------------------------

Model Performance Comparision Matrix

--------------------------------------------------------------------------------

                  Model   Accuracy  Precision     Recall   F1 Score

3          CNN_Adam_Opt  75.388889  75.394187  75.388889  75.387605

2        CNN_Leaky_ReLU  74.333333  74.901959  74.333333  74.185970

0       Basic_CNN_Model  74.111111  74.163734  74.111111  74.097008

1  CNN Model_Batch_Norm  72.333333  72.794399  72.333333  72.192718

--------------------------------------------------------------------------------

Conclusion¶

Based on the provided classification matrices and performance metrics, let's compare the four models for pneumonia detection and draw some conclusions:

Model 1:

Accuracy: 74% Precision (Class 1): 75% Recall (Class 1): 72% F1-score (Class 1): 73%

Model 2:

Accuracy: 73% Precision (Class 1): 70% Recall (Class 1): 79% F1-score (Class 1): 74%

Model 3:

Accuracy: 75% Precision (Class 1): 79% Recall (Class 1): 67% F1-score (Class 1): 72%

Model 4:

Accuracy: 75% Precision (Class 1): 75% Recall (Class 1): 76% F1-score (Class 1): 76%

Comparison and Inferences:

Model 1 vs. Model 2:

Model 1 has a slightly higher accuracy, precision for class 1 compared to Model 2. Model 2 performs slightly better in correctly identifying positive cases (pneumonia cases) due to higher recall for class 1. Model 2 has a lower precision, indicating that it has more false positives compared to Model 1.

Model 2 vs. Model 3:

Model 3 has slightly better accuracy and precision for class 1 than Model 2. Model 2, however, has higher recall for class 1, indicating it is better at capturing actual positive cases.

Model 3 vs. Model 4:

Model 4 has higher recall, and F1-score for class 1 compared to Model 3. Model 3 has slightly higher precision but lower performance in correctly identifying positive cases (lower recall).

Conclusion:

Among the four models, Model 4 seems to be the best performer for pneumonia detection based on its overall balanced performance across various metrics. It has a good balance between precision and recall for class 1, which indicates it can effectively detect pneumonia cases while minimizing false positives. Model 3 has the highest precision for class 1, but its recall is the least. This means that Model 3 may have fewer false positives, but it could potentially miss some positive cases.

Model 1 and Model 4 exhibit similar performance, with Model 4 having slightly better recall and better F1-score for the same class.

Overall, the choice of the "best" model depends on the specific trade-off between false positives and false negatives that is acceptable in your application.

  • If minimizing false positives (misdiagnosing healthy patients as having pneumonia) is a priority, then a model with higher precision may be preferred.
  • On the other hand, if correctly identifying positive cases (recall) is more important, then a model with higher recall would be favored.

For the current problem statement, Model 4 seems to be the best choice for further use.

MILESTONE 2¶

Step 1: Fine tune the trained basic CNN models for classification.¶

Fine tuning with Grid Search Model¶

Hyperparameter tuning or optimization is important in any machine learning model training activity. The hyperparameters of a model cannot be determined from the given datasets through the learning process. However, they are very crucial to control the learning process itself. These hyperparameters originate from the mathematical formulation of machine learning models. For example, the weights learned while training a linear regression model are parameters, but the learning rate in gradient descent is a hyperparameter. The performance of a model on a dataset significantly depends on the proper tuning, i.e., finding the best combination of the model hyperparameters.

Different techniques are available for hyperparameter optimization, such as Grid Search, Randomized Search, Bayesian Optimization, etc.

Grid Search and Randomized Search are two widely used techniques in Hyperparameter Tuning. Grid Search exhaustively searches through every combination of the hyperparameter values specified. In contrast to Grid Search, not all given parameter values are tried out in Randomized Search. Rather a fixed number of parameter settings is sampled from the specified distributions. Sampling without replacement is performed if all parameters are presented as a list. Sampling with replacement is used if at least one parameter is given as a distribution. For each hyperparameter, either a distribution over possible values or a list of discrete values (to be sampled uniformly) can be specified. For the hyperparameters having continuous values, a continuous distribution should be specified to take full advantage of the randomization. The major benefit of this search is a decreased processing time.

HyperParamter Tuning for best model of Milestone 1

We will pick up the best model from Milestone 1 and run Grid Search using the parameters: Optimizer, activation and learning_rate.

The new model will be created using the best parameter from gridSearch results.

In [ ]:
# Define your original model creation function
def create_model(optimizer='adam', hidden_units=512, dropout_rate=0.5,
                 activation='relu', learning_rate=0.001,
                 weight_init='he_normal'):
    if optimizer == 'adam':
        opt = Adam(learning_rate=learning_rate)
    elif optimizer == 'sgd':
        opt = SGD(learning_rate=learning_rate)
    else:
        raise ValueError('Invalid optimizer')

    model = Sequential()
    model.add(Conv2D(32, (3, 3), activation=activation, input_shape=(32, 32, 1)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(64, (3, 3), activation=activation))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(128, (3, 3), activation=activation))
    model.add(MaxPooling2D((2, 2)))
    model.add(Flatten())
    model.add(Dense(512, activation=LeakyReLU(alpha=0.1)))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
    model.summary()
    return model

# Wrap Keras model with KerasClassifier
model = KerasClassifier(build_fn=create_model, epochs=12, verbose=1)

# Define the hyperparameter grid
param_grid = {
    'optimizer': ['adam', 'sgd'],
    'activation': ['relu' , 'LeakyReLU'],
    'learning_rate': [0.0001, 0.001, 0.01],
    }

# Create GridSearchCV instance
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=3)

# Fit the grid search
grid_result = grid_search.fit(X_train, y_train)

# Print the best parameters and best score
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))

means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print("%f (%f) with: %r" % (mean, stdev, param))
Model: "sequential_76"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_228 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_228 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_229 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_229 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_230 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_230 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_76 (Flatten)        (None, 512)               0         

                                                                 

 dense_152 (Dense)           (None, 512)               262656    

                                                                 

 dropout_74 (Dropout)        (None, 512)               0         

                                                                 

 dense_153 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________
/tmp/ipykernel_28/416103543.py:28: DeprecationWarning: KerasClassifier is deprecated, use Sci-Keras (https://github.com/adriangb/scikeras) instead. See https://www.adriangb.com/scikeras/stable/migration.html for help migrating.

  model = KerasClassifier(build_fn=create_model, epochs=12, verbose=1)
Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.6003 - acc: 0.6748 - precision: 0.6928 - recall: 0.6858

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5516 - acc: 0.7307 - precision: 0.7227 - recall: 0.7420

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5388 - acc: 0.7409 - precision: 0.7345 - recall: 0.7485

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5313 - acc: 0.7409 - precision: 0.7343 - recall: 0.7488

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5186 - acc: 0.7452 - precision: 0.7414 - recall: 0.7470

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5070 - acc: 0.7645 - precision: 0.7611 - recall: 0.7657

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5021 - acc: 0.7600 - precision: 0.7556 - recall: 0.7632

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4956 - acc: 0.7593 - precision: 0.7542 - recall: 0.7639

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4796 - acc: 0.7721 - precision: 0.7708 - recall: 0.7697

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4693 - acc: 0.7798 - precision: 0.7757 - recall: 0.7827

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4578 - acc: 0.7879 - precision: 0.7822 - recall: 0.7935

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4433 - acc: 0.7955 - precision: 0.7873 - recall: 0.8057

88/88 [==============================] - 1s 4ms/step - loss: 0.5357 - acc: 0.7525 - precision: 0.7324 - recall: 0.8072

Model: "sequential_77"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_231 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_231 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_232 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_232 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_233 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_233 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_77 (Flatten)        (None, 512)               0         

                                                                 

 dense_154 (Dense)           (None, 512)               262656    

                                                                 

 dropout_75 (Dropout)        (None, 512)               0         

                                                                 

 dense_155 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5908 - acc: 0.6854 - precision: 0.6987 - recall: 0.7419

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5506 - acc: 0.7243 - precision: 0.7220 - recall: 0.7378

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5392 - acc: 0.7366 - precision: 0.7333 - recall: 0.7512

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5324 - acc: 0.7407 - precision: 0.7342 - recall: 0.7622

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5267 - acc: 0.7454 - precision: 0.7437 - recall: 0.7558

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5215 - acc: 0.7529 - precision: 0.7490 - recall: 0.7675

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5173 - acc: 0.7511 - precision: 0.7421 - recall: 0.7767

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5067 - acc: 0.7550 - precision: 0.7521 - recall: 0.7675

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5081 - acc: 0.7529 - precision: 0.7476 - recall: 0.7703

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4954 - acc: 0.7604 - precision: 0.7545 - recall: 0.7785

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4835 - acc: 0.7705 - precision: 0.7656 - recall: 0.7859

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4790 - acc: 0.7684 - precision: 0.7630 - recall: 0.7849

88/88 [==============================] - 1s 3ms/step - loss: 0.5317 - acc: 0.7457 - precision: 0.7028 - recall: 0.8348

Model: "sequential_78"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_234 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_234 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_235 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_235 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_236 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_236 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_78 (Flatten)        (None, 512)               0         

                                                                 

 dense_156 (Dense)           (None, 512)               262656    

                                                                 

 dropout_76 (Dropout)        (None, 512)               0         

                                                                 

 dense_157 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5941 - acc: 0.6829 - precision: 0.6864 - recall: 0.7424

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5548 - acc: 0.7202 - precision: 0.7129 - recall: 0.7356

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5410 - acc: 0.7345 - precision: 0.7311 - recall: 0.7403

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5288 - acc: 0.7414 - precision: 0.7317 - recall: 0.7610

Epoch 5/12

175/175 [==============================] - 1s 7ms/step - loss: 0.5225 - acc: 0.7495 - precision: 0.7423 - recall: 0.7628

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5129 - acc: 0.7518 - precision: 0.7412 - recall: 0.7725

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5069 - acc: 0.7564 - precision: 0.7490 - recall: 0.7699

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4973 - acc: 0.7673 - precision: 0.7597 - recall: 0.7807

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4871 - acc: 0.7696 - precision: 0.7625 - recall: 0.7821

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7759 - precision: 0.7700 - recall: 0.7857

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4683 - acc: 0.7773 - precision: 0.7699 - recall: 0.7900

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4557 - acc: 0.7850 - precision: 0.7808 - recall: 0.7914

88/88 [==============================] - 1s 4ms/step - loss: 0.5489 - acc: 0.7389 - precision: 0.7157 - recall: 0.7957

Model: "sequential_79"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_237 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_237 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_238 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_238 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_239 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_239 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_79 (Flatten)        (None, 512)               0         

                                                                 

 dense_158 (Dense)           (None, 512)               262656    

                                                                 

 dropout_77 (Dropout)        (None, 512)               0         

                                                                 

 dense_159 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.6022 - acc: 0.6711 - precision: 0.6882 - recall: 0.7039

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5479 - acc: 0.7280 - precision: 0.7219 - recall: 0.7352

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5371 - acc: 0.7389 - precision: 0.7315 - recall: 0.7488

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5315 - acc: 0.7354 - precision: 0.7289 - recall: 0.7431

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5184 - acc: 0.7489 - precision: 0.7442 - recall: 0.7528

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5096 - acc: 0.7564 - precision: 0.7531 - recall: 0.7575

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5047 - acc: 0.7577 - precision: 0.7548 - recall: 0.7578

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5044 - acc: 0.7525 - precision: 0.7460 - recall: 0.7600

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4809 - acc: 0.7718 - precision: 0.7655 - recall: 0.7787

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4706 - acc: 0.7748 - precision: 0.7718 - recall: 0.7755

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4558 - acc: 0.7859 - precision: 0.7819 - recall: 0.7884

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4463 - acc: 0.7927 - precision: 0.7889 - recall: 0.7949

88/88 [==============================] - 1s 3ms/step - loss: 0.5486 - acc: 0.7425 - precision: 0.7210 - recall: 0.8037

Model: "sequential_80"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_240 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_240 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_241 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_241 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_242 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_242 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_80 (Flatten)        (None, 512)               0         

                                                                 

 dense_160 (Dense)           (None, 512)               262656    

                                                                 

 dropout_78 (Dropout)        (None, 512)               0         

                                                                 

 dense_161 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5881 - acc: 0.6871 - precision: 0.6982 - recall: 0.7358

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5536 - acc: 0.7211 - precision: 0.7181 - recall: 0.7364

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5390 - acc: 0.7366 - precision: 0.7329 - recall: 0.7523

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5338 - acc: 0.7427 - precision: 0.7366 - recall: 0.7629

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5283 - acc: 0.7396 - precision: 0.7359 - recall: 0.7551

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5237 - acc: 0.7541 - precision: 0.7525 - recall: 0.7640

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5162 - acc: 0.7548 - precision: 0.7506 - recall: 0.7700

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5087 - acc: 0.7602 - precision: 0.7545 - recall: 0.7778

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5016 - acc: 0.7620 - precision: 0.7579 - recall: 0.7764

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4952 - acc: 0.7688 - precision: 0.7630 - recall: 0.7859

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4844 - acc: 0.7696 - precision: 0.7639 - recall: 0.7866

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4782 - acc: 0.7764 - precision: 0.7690 - recall: 0.7962

88/88 [==============================] - 1s 3ms/step - loss: 0.5121 - acc: 0.7511 - precision: 0.7320 - recall: 0.7773

Model: "sequential_81"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_243 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_243 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_244 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_244 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_245 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_245 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_81 (Flatten)        (None, 512)               0         

                                                                 

 dense_162 (Dense)           (None, 512)               262656    

                                                                 

 dropout_79 (Dropout)        (None, 512)               0         

                                                                 

 dense_163 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.6011 - acc: 0.6779 - precision: 0.6924 - recall: 0.7198

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5557 - acc: 0.7180 - precision: 0.7101 - recall: 0.7352

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5418 - acc: 0.7273 - precision: 0.7200 - recall: 0.7424

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5275 - acc: 0.7448 - precision: 0.7363 - recall: 0.7614

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5216 - acc: 0.7496 - precision: 0.7441 - recall: 0.7596

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5152 - acc: 0.7491 - precision: 0.7390 - recall: 0.7689

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5102 - acc: 0.7552 - precision: 0.7505 - recall: 0.7631

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4997 - acc: 0.7636 - precision: 0.7571 - recall: 0.7750

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4926 - acc: 0.7598 - precision: 0.7535 - recall: 0.7710

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4808 - acc: 0.7721 - precision: 0.7662 - recall: 0.7821

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4729 - acc: 0.7750 - precision: 0.7698 - recall: 0.7835

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4638 - acc: 0.7862 - precision: 0.7817 - recall: 0.7932

88/88 [==============================] - 1s 3ms/step - loss: 0.5266 - acc: 0.7461 - precision: 0.7496 - recall: 0.7416

Model: "sequential_82"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_246 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_246 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_247 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_247 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_248 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_248 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_82 (Flatten)        (None, 512)               0         

                                                                 

 dense_164 (Dense)           (None, 512)               262656    

                                                                 

 dropout_80 (Dropout)        (None, 512)               0         

                                                                 

 dense_165 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.6022 - acc: 0.6723 - precision: 0.6983 - recall: 0.6893

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5489 - acc: 0.7291 - precision: 0.7206 - recall: 0.7416

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5393 - acc: 0.7364 - precision: 0.7276 - recall: 0.7496

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5335 - acc: 0.7325 - precision: 0.7264 - recall: 0.7395

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5221 - acc: 0.7432 - precision: 0.7362 - recall: 0.7521

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5128 - acc: 0.7527 - precision: 0.7456 - recall: 0.7614

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5054 - acc: 0.7579 - precision: 0.7529 - recall: 0.7621

Epoch 8/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4960 - acc: 0.7561 - precision: 0.7492 - recall: 0.7643

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4830 - acc: 0.7723 - precision: 0.7663 - recall: 0.7787

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4739 - acc: 0.7752 - precision: 0.7728 - recall: 0.7747

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4630 - acc: 0.7857 - precision: 0.7847 - recall: 0.7830

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4496 - acc: 0.7884 - precision: 0.7853 - recall: 0.7895

88/88 [==============================] - 1s 3ms/step - loss: 0.5385 - acc: 0.7475 - precision: 0.7254 - recall: 0.8086

Model: "sequential_83"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_249 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_249 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_250 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_250 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_251 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_251 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_83 (Flatten)        (None, 512)               0         

                                                                 

 dense_166 (Dense)           (None, 512)               262656    

                                                                 

 dropout_81 (Dropout)        (None, 512)               0         

                                                                 

 dense_167 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5898 - acc: 0.6889 - precision: 0.7032 - recall: 0.7325

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5506 - acc: 0.7273 - precision: 0.7250 - recall: 0.7406

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5368 - acc: 0.7411 - precision: 0.7361 - recall: 0.7590

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5316 - acc: 0.7421 - precision: 0.7375 - recall: 0.7594

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5222 - acc: 0.7461 - precision: 0.7426 - recall: 0.7604

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5151 - acc: 0.7534 - precision: 0.7482 - recall: 0.7707

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5092 - acc: 0.7555 - precision: 0.7499 - recall: 0.7735

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5008 - acc: 0.7625 - precision: 0.7590 - recall: 0.7757

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4928 - acc: 0.7677 - precision: 0.7616 - recall: 0.7856

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4812 - acc: 0.7779 - precision: 0.7713 - recall: 0.7958

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4697 - acc: 0.7823 - precision: 0.7770 - recall: 0.7976

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4591 - acc: 0.7861 - precision: 0.7817 - recall: 0.7994

88/88 [==============================] - 1s 3ms/step - loss: 0.5112 - acc: 0.7543 - precision: 0.7311 - recall: 0.7897

Model: "sequential_84"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_252 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_252 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_253 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_253 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_254 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_254 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_84 (Flatten)        (None, 512)               0         

                                                                 

 dense_168 (Dense)           (None, 512)               262656    

                                                                 

 dropout_82 (Dropout)        (None, 512)               0         

                                                                 

 dense_169 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5984 - acc: 0.6764 - precision: 0.6930 - recall: 0.7186

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5518 - acc: 0.7230 - precision: 0.7154 - recall: 0.7392

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5393 - acc: 0.7305 - precision: 0.7242 - recall: 0.7431

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5262 - acc: 0.7427 - precision: 0.7357 - recall: 0.7560

Epoch 5/12

175/175 [==============================] - 1s 6ms/step - loss: 0.5186 - acc: 0.7539 - precision: 0.7490 - recall: 0.7624

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5122 - acc: 0.7493 - precision: 0.7394 - recall: 0.7685

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5063 - acc: 0.7588 - precision: 0.7530 - recall: 0.7689

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4993 - acc: 0.7600 - precision: 0.7506 - recall: 0.7775

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7655 - precision: 0.7571 - recall: 0.7807

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4766 - acc: 0.7743 - precision: 0.7685 - recall: 0.7839

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4734 - acc: 0.7780 - precision: 0.7696 - recall: 0.7925

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4634 - acc: 0.7809 - precision: 0.7722 - recall: 0.7957

88/88 [==============================] - 1s 5ms/step - loss: 0.5463 - acc: 0.7346 - precision: 0.7108 - recall: 0.7943

Model: "sequential_85"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_255 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_255 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_256 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_256 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_257 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_257 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_85 (Flatten)        (None, 512)               0         

                                                                 

 dense_170 (Dense)           (None, 512)               262656    

                                                                 

 dropout_83 (Dropout)        (None, 512)               0         

                                                                 

 dense_171 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.6161 - acc: 0.6539 - precision: 0.6742 - recall: 0.6953

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5525 - acc: 0.7225 - precision: 0.7139 - recall: 0.7355

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5392 - acc: 0.7354 - precision: 0.7284 - recall: 0.7442

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5392 - acc: 0.7307 - precision: 0.7250 - recall: 0.7370

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5227 - acc: 0.7430 - precision: 0.7389 - recall: 0.7456

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5151 - acc: 0.7484 - precision: 0.7409 - recall: 0.7582

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5123 - acc: 0.7513 - precision: 0.7442 - recall: 0.7600

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5067 - acc: 0.7475 - precision: 0.7397 - recall: 0.7578

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4930 - acc: 0.7605 - precision: 0.7557 - recall: 0.7647

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4844 - acc: 0.7684 - precision: 0.7658 - recall: 0.7683

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4679 - acc: 0.7763 - precision: 0.7710 - recall: 0.7812

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4620 - acc: 0.7859 - precision: 0.7805 - recall: 0.7909

88/88 [==============================] - 1s 3ms/step - loss: 0.5265 - acc: 0.7579 - precision: 0.7386 - recall: 0.8093

Model: "sequential_86"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_258 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_258 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_259 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_259 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_260 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_260 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_86 (Flatten)        (None, 512)               0         

                                                                 

 dense_172 (Dense)           (None, 512)               262656    

                                                                 

 dropout_84 (Dropout)        (None, 512)               0         

                                                                 

 dense_173 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 6ms/step - loss: 0.5872 - acc: 0.6925 - precision: 0.7088 - recall: 0.7382

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5496 - acc: 0.7284 - precision: 0.7251 - recall: 0.7438

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5366 - acc: 0.7423 - precision: 0.7361 - recall: 0.7629

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5280 - acc: 0.7434 - precision: 0.7383 - recall: 0.7615

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5210 - acc: 0.7480 - precision: 0.7476 - recall: 0.7558

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5158 - acc: 0.7568 - precision: 0.7491 - recall: 0.7788

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5095 - acc: 0.7559 - precision: 0.7496 - recall: 0.7753

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5024 - acc: 0.7627 - precision: 0.7559 - recall: 0.7824

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4924 - acc: 0.7661 - precision: 0.7616 - recall: 0.7810

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4860 - acc: 0.7688 - precision: 0.7605 - recall: 0.7909

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4709 - acc: 0.7818 - precision: 0.7785 - recall: 0.7933

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4620 - acc: 0.7854 - precision: 0.7790 - recall: 0.8022

88/88 [==============================] - 1s 4ms/step - loss: 0.5303 - acc: 0.7414 - precision: 0.7110 - recall: 0.7969

Model: "sequential_87"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_261 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_261 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_262 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_262 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_263 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_263 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_87 (Flatten)        (None, 512)               0         

                                                                 

 dense_174 (Dense)           (None, 512)               262656    

                                                                 

 dropout_85 (Dropout)        (None, 512)               0         

                                                                 

 dense_175 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.6004 - acc: 0.6800 - precision: 0.6886 - recall: 0.7239

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5536 - acc: 0.7230 - precision: 0.7158 - recall: 0.7381

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5433 - acc: 0.7277 - precision: 0.7233 - recall: 0.7360

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5279 - acc: 0.7430 - precision: 0.7361 - recall: 0.7564

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5288 - acc: 0.7459 - precision: 0.7415 - recall: 0.7535

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5203 - acc: 0.7464 - precision: 0.7390 - recall: 0.7606

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5150 - acc: 0.7538 - precision: 0.7484 - recall: 0.7631

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5069 - acc: 0.7591 - precision: 0.7514 - recall: 0.7732

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5028 - acc: 0.7621 - precision: 0.7553 - recall: 0.7742

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4903 - acc: 0.7688 - precision: 0.7611 - recall: 0.7821

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4871 - acc: 0.7691 - precision: 0.7599 - recall: 0.7857

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4816 - acc: 0.7736 - precision: 0.7684 - recall: 0.7821

88/88 [==============================] - 1s 4ms/step - loss: 0.5515 - acc: 0.7343 - precision: 0.6975 - recall: 0.8306

Model: "sequential_88"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_264 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_264 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_265 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_265 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_266 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_266 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_88 (Flatten)        (None, 512)               0         

                                                                 

 dense_176 (Dense)           (None, 512)               262656    

                                                                 

 dropout_86 (Dropout)        (None, 512)               0         

                                                                 

 dense_177 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.6113 - acc: 0.6580 - precision: 0.6720 - recall: 0.7120

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5509 - acc: 0.7245 - precision: 0.7144 - recall: 0.7409

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5410 - acc: 0.7330 - precision: 0.7249 - recall: 0.7445

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5350 - acc: 0.7336 - precision: 0.7262 - recall: 0.7434

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5275 - acc: 0.7420 - precision: 0.7382 - recall: 0.7438

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5171 - acc: 0.7477 - precision: 0.7400 - recall: 0.7578

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5155 - acc: 0.7500 - precision: 0.7467 - recall: 0.7510

Epoch 8/12

175/175 [==============================] - 1s 6ms/step - loss: 0.5059 - acc: 0.7534 - precision: 0.7468 - recall: 0.7611

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4943 - acc: 0.7607 - precision: 0.7549 - recall: 0.7668

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4851 - acc: 0.7659 - precision: 0.7635 - recall: 0.7654

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4733 - acc: 0.7725 - precision: 0.7681 - recall: 0.7758

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4643 - acc: 0.7779 - precision: 0.7717 - recall: 0.7845

88/88 [==============================] - 1s 3ms/step - loss: 0.5292 - acc: 0.7468 - precision: 0.7231 - recall: 0.8121

Model: "sequential_89"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_267 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_267 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_268 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_268 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_269 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_269 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_89 (Flatten)        (None, 512)               0         

                                                                 

 dense_178 (Dense)           (None, 512)               262656    

                                                                 

 dropout_87 (Dropout)        (None, 512)               0         

                                                                 

 dense_179 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5955 - acc: 0.6809 - precision: 0.6957 - recall: 0.7328

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5488 - acc: 0.7248 - precision: 0.7209 - recall: 0.7420

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5384 - acc: 0.7391 - precision: 0.7358 - recall: 0.7537

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5297 - acc: 0.7416 - precision: 0.7349 - recall: 0.7633

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5223 - acc: 0.7432 - precision: 0.7391 - recall: 0.7590

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5142 - acc: 0.7566 - precision: 0.7504 - recall: 0.7757

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5091 - acc: 0.7536 - precision: 0.7478 - recall: 0.7721

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4988 - acc: 0.7650 - precision: 0.7620 - recall: 0.7771

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4935 - acc: 0.7673 - precision: 0.7598 - recall: 0.7880

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4820 - acc: 0.7723 - precision: 0.7673 - recall: 0.7877

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4686 - acc: 0.7786 - precision: 0.7733 - recall: 0.7941

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4552 - acc: 0.7911 - precision: 0.7875 - recall: 0.8025

88/88 [==============================] - 1s 3ms/step - loss: 0.5356 - acc: 0.7446 - precision: 0.7155 - recall: 0.7962

Model: "sequential_90"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_270 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_270 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_271 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_271 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_272 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_272 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_90 (Flatten)        (None, 512)               0         

                                                                 

 dense_180 (Dense)           (None, 512)               262656    

                                                                 

 dropout_88 (Dropout)        (None, 512)               0         

                                                                 

 dense_181 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5894 - acc: 0.6936 - precision: 0.6962 - recall: 0.7397

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5526 - acc: 0.7259 - precision: 0.7162 - recall: 0.7467

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5393 - acc: 0.7321 - precision: 0.7240 - recall: 0.7488

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5289 - acc: 0.7445 - precision: 0.7358 - recall: 0.7614

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5212 - acc: 0.7486 - precision: 0.7432 - recall: 0.7581

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5146 - acc: 0.7495 - precision: 0.7392 - recall: 0.7696

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5095 - acc: 0.7543 - precision: 0.7454 - recall: 0.7710

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5041 - acc: 0.7627 - precision: 0.7524 - recall: 0.7818

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4917 - acc: 0.7704 - precision: 0.7615 - recall: 0.7860

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4837 - acc: 0.7734 - precision: 0.7679 - recall: 0.7825

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4716 - acc: 0.7786 - precision: 0.7662 - recall: 0.8007

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4648 - acc: 0.7839 - precision: 0.7760 - recall: 0.7971

88/88 [==============================] - 1s 3ms/step - loss: 0.5559 - acc: 0.7325 - precision: 0.7144 - recall: 0.7779

Model: "sequential_91"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_273 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_273 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_274 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_274 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_275 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_275 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_91 (Flatten)        (None, 512)               0         

                                                                 

 dense_182 (Dense)           (None, 512)               262656    

                                                                 

 dropout_89 (Dropout)        (None, 512)               0         

                                                                 

 dense_183 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.6128 - acc: 0.6614 - precision: 0.6803 - recall: 0.6938

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5534 - acc: 0.7216 - precision: 0.7154 - recall: 0.7290

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5416 - acc: 0.7323 - precision: 0.7242 - recall: 0.7438

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5365 - acc: 0.7318 - precision: 0.7267 - recall: 0.7366

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5234 - acc: 0.7430 - precision: 0.7379 - recall: 0.7478

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5150 - acc: 0.7514 - precision: 0.7432 - recall: 0.7625

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5102 - acc: 0.7529 - precision: 0.7480 - recall: 0.7571

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5028 - acc: 0.7584 - precision: 0.7539 - recall: 0.7618

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4875 - acc: 0.7638 - precision: 0.7611 - recall: 0.7636

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4803 - acc: 0.7654 - precision: 0.7645 - recall: 0.7618

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4636 - acc: 0.7775 - precision: 0.7774 - recall: 0.7729

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4530 - acc: 0.7845 - precision: 0.7833 - recall: 0.7819

88/88 [==============================] - 1s 3ms/step - loss: 0.5573 - acc: 0.7400 - precision: 0.7148 - recall: 0.8114

Model: "sequential_92"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_276 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_276 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_277 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_277 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_278 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_278 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_92 (Flatten)        (None, 512)               0         

                                                                 

 dense_184 (Dense)           (None, 512)               262656    

                                                                 

 dropout_90 (Dropout)        (None, 512)               0         

                                                                 

 dense_185 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.6007 - acc: 0.6761 - precision: 0.6914 - recall: 0.7250

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7300 - precision: 0.7273 - recall: 0.7438

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5362 - acc: 0.7412 - precision: 0.7375 - recall: 0.7565

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5294 - acc: 0.7477 - precision: 0.7415 - recall: 0.7675

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5232 - acc: 0.7511 - precision: 0.7491 - recall: 0.7619

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5142 - acc: 0.7546 - precision: 0.7464 - recall: 0.7781

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5093 - acc: 0.7521 - precision: 0.7464 - recall: 0.7707

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5019 - acc: 0.7641 - precision: 0.7612 - recall: 0.7760

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4973 - acc: 0.7675 - precision: 0.7606 - recall: 0.7870

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4874 - acc: 0.7696 - precision: 0.7657 - recall: 0.7831

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4733 - acc: 0.7816 - precision: 0.7759 - recall: 0.7976

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4671 - acc: 0.7841 - precision: 0.7802 - recall: 0.7965

88/88 [==============================] - 1s 4ms/step - loss: 0.5445 - acc: 0.7418 - precision: 0.7006 - recall: 0.8275

Model: "sequential_93"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_279 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_279 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_280 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_280 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_281 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_281 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_93 (Flatten)        (None, 512)               0         

                                                                 

 dense_186 (Dense)           (None, 512)               262656    

                                                                 

 dropout_91 (Dropout)        (None, 512)               0         

                                                                 

 dense_187 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5980 - acc: 0.6873 - precision: 0.6866 - recall: 0.7479

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7302 - precision: 0.7235 - recall: 0.7435

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5380 - acc: 0.7345 - precision: 0.7285 - recall: 0.7460

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5252 - acc: 0.7468 - precision: 0.7390 - recall: 0.7617

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5153 - acc: 0.7548 - precision: 0.7486 - recall: 0.7660

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5049 - acc: 0.7548 - precision: 0.7453 - recall: 0.7728

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5015 - acc: 0.7580 - precision: 0.7503 - recall: 0.7721

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4887 - acc: 0.7655 - precision: 0.7576 - recall: 0.7796

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7746 - precision: 0.7659 - recall: 0.7900

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4680 - acc: 0.7820 - precision: 0.7759 - recall: 0.7918

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4567 - acc: 0.7857 - precision: 0.7770 - recall: 0.8004

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4470 - acc: 0.7909 - precision: 0.7839 - recall: 0.8021

88/88 [==============================] - 1s 3ms/step - loss: 0.5564 - acc: 0.7296 - precision: 0.6971 - recall: 0.8157

Model: "sequential_94"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_282 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_282 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_283 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_283 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_284 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_284 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_94 (Flatten)        (None, 512)               0         

                                                                 

 dense_188 (Dense)           (None, 512)               262656    

                                                                 

 dropout_92 (Dropout)        (None, 512)               0         

                                                                 

 dense_189 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5824 - acc: 0.6936 - precision: 0.6925 - recall: 0.7357

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5417 - acc: 0.7354 - precision: 0.7271 - recall: 0.7470

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5281 - acc: 0.7423 - precision: 0.7367 - recall: 0.7481

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5228 - acc: 0.7454 - precision: 0.7378 - recall: 0.7553

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5076 - acc: 0.7521 - precision: 0.7471 - recall: 0.7567

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4870 - acc: 0.7686 - precision: 0.7623 - recall: 0.7755

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4791 - acc: 0.7789 - precision: 0.7718 - recall: 0.7873

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4631 - acc: 0.7814 - precision: 0.7766 - recall: 0.7855

Epoch 9/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4455 - acc: 0.8007 - precision: 0.7910 - recall: 0.8132

Epoch 10/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4154 - acc: 0.8109 - precision: 0.8035 - recall: 0.8194

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.3880 - acc: 0.8259 - precision: 0.8172 - recall: 0.8363

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.3695 - acc: 0.8388 - precision: 0.8303 - recall: 0.8485

88/88 [==============================] - 1s 5ms/step - loss: 0.5828 - acc: 0.7407 - precision: 0.7154 - recall: 0.8121

Model: "sequential_95"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_285 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_285 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_286 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_286 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_287 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_287 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_95 (Flatten)        (None, 512)               0         

                                                                 

 dense_190 (Dense)           (None, 512)               262656    

                                                                 

 dropout_93 (Dropout)        (None, 512)               0         

                                                                 

 dense_191 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5822 - acc: 0.6948 - precision: 0.7019 - recall: 0.7417

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5465 - acc: 0.7304 - precision: 0.7312 - recall: 0.7364

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5337 - acc: 0.7445 - precision: 0.7401 - recall: 0.7608

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5269 - acc: 0.7468 - precision: 0.7382 - recall: 0.7721

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5133 - acc: 0.7564 - precision: 0.7512 - recall: 0.7735

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5029 - acc: 0.7634 - precision: 0.7547 - recall: 0.7870

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7705 - precision: 0.7627 - recall: 0.7916

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7759 - precision: 0.7689 - recall: 0.7948

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4684 - acc: 0.7818 - precision: 0.7767 - recall: 0.7965

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4500 - acc: 0.7854 - precision: 0.7775 - recall: 0.8050

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4257 - acc: 0.8011 - precision: 0.7952 - recall: 0.8160

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4037 - acc: 0.8123 - precision: 0.8102 - recall: 0.8202

88/88 [==============================] - 1s 3ms/step - loss: 0.5534 - acc: 0.7500 - precision: 0.7259 - recall: 0.7882

Model: "sequential_96"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_288 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_288 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_289 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_289 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_290 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_290 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_96 (Flatten)        (None, 512)               0         

                                                                 

 dense_192 (Dense)           (None, 512)               262656    

                                                                 

 dropout_94 (Dropout)        (None, 512)               0         

                                                                 

 dense_193 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5858 - acc: 0.6932 - precision: 0.7013 - recall: 0.7316

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5461 - acc: 0.7257 - precision: 0.7174 - recall: 0.7431

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5332 - acc: 0.7389 - precision: 0.7321 - recall: 0.7521

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5191 - acc: 0.7518 - precision: 0.7410 - recall: 0.7728

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5046 - acc: 0.7557 - precision: 0.7499 - recall: 0.7660

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4900 - acc: 0.7595 - precision: 0.7502 - recall: 0.7767

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4773 - acc: 0.7757 - precision: 0.7653 - recall: 0.7943

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4643 - acc: 0.7793 - precision: 0.7702 - recall: 0.7950

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4417 - acc: 0.7966 - precision: 0.7830 - recall: 0.8197

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4175 - acc: 0.8086 - precision: 0.7990 - recall: 0.8236

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3992 - acc: 0.8118 - precision: 0.7956 - recall: 0.8383

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3702 - acc: 0.8296 - precision: 0.8193 - recall: 0.8451

88/88 [==============================] - 1s 3ms/step - loss: 0.5715 - acc: 0.7386 - precision: 0.7215 - recall: 0.7801

Model: "sequential_97"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_291 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_291 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_292 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_292 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_293 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_293 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_97 (Flatten)        (None, 512)               0         

                                                                 

 dense_194 (Dense)           (None, 512)               262656    

                                                                 

 dropout_95 (Dropout)        (None, 512)               0         

                                                                 

 dense_195 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5890 - acc: 0.6814 - precision: 0.6950 - recall: 0.7106

Epoch 2/12

175/175 [==============================] - 1s 6ms/step - loss: 0.5424 - acc: 0.7304 - precision: 0.7230 - recall: 0.7402

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5327 - acc: 0.7384 - precision: 0.7330 - recall: 0.7438

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5230 - acc: 0.7484 - precision: 0.7385 - recall: 0.7632

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5075 - acc: 0.7502 - precision: 0.7438 - recall: 0.7575

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4921 - acc: 0.7671 - precision: 0.7598 - recall: 0.7762

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4818 - acc: 0.7779 - precision: 0.7709 - recall: 0.7859

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4690 - acc: 0.7793 - precision: 0.7733 - recall: 0.7855

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4415 - acc: 0.7946 - precision: 0.7877 - recall: 0.8024

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4140 - acc: 0.8161 - precision: 0.8087 - recall: 0.8244

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3829 - acc: 0.8311 - precision: 0.8251 - recall: 0.8370

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3587 - acc: 0.8371 - precision: 0.8321 - recall: 0.8417

88/88 [==============================] - 1s 3ms/step - loss: 0.5813 - acc: 0.7404 - precision: 0.7230 - recall: 0.7917

Model: "sequential_98"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_294 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_294 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_295 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_295 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_296 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_296 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_98 (Flatten)        (None, 512)               0         

                                                                 

 dense_196 (Dense)           (None, 512)               262656    

                                                                 

 dropout_96 (Dropout)        (None, 512)               0         

                                                                 

 dense_197 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5821 - acc: 0.6934 - precision: 0.7026 - recall: 0.7360

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5497 - acc: 0.7257 - precision: 0.7255 - recall: 0.7343

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5355 - acc: 0.7434 - precision: 0.7407 - recall: 0.7562

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5298 - acc: 0.7475 - precision: 0.7388 - recall: 0.7728

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5184 - acc: 0.7527 - precision: 0.7462 - recall: 0.7728

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5052 - acc: 0.7614 - precision: 0.7560 - recall: 0.7785

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4979 - acc: 0.7664 - precision: 0.7587 - recall: 0.7877

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4854 - acc: 0.7759 - precision: 0.7700 - recall: 0.7926

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4715 - acc: 0.7830 - precision: 0.7767 - recall: 0.8001

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4618 - acc: 0.7841 - precision: 0.7749 - recall: 0.8064

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4354 - acc: 0.8016 - precision: 0.7930 - recall: 0.8213

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4161 - acc: 0.8130 - precision: 0.8073 - recall: 0.8270

88/88 [==============================] - 1s 5ms/step - loss: 0.5338 - acc: 0.7496 - precision: 0.7375 - recall: 0.7606

Model: "sequential_99"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_297 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_297 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_298 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_298 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_299 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_299 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_99 (Flatten)        (None, 512)               0         

                                                                 

 dense_198 (Dense)           (None, 512)               262656    

                                                                 

 dropout_97 (Dropout)        (None, 512)               0         

                                                                 

 dense_199 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5847 - acc: 0.6936 - precision: 0.7035 - recall: 0.7263

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5508 - acc: 0.7257 - precision: 0.7196 - recall: 0.7381

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5364 - acc: 0.7366 - precision: 0.7344 - recall: 0.7399

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5190 - acc: 0.7468 - precision: 0.7373 - recall: 0.7653

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5071 - acc: 0.7563 - precision: 0.7479 - recall: 0.7717

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4915 - acc: 0.7627 - precision: 0.7547 - recall: 0.7771

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4804 - acc: 0.7713 - precision: 0.7627 - recall: 0.7864

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4697 - acc: 0.7807 - precision: 0.7721 - recall: 0.7953

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4554 - acc: 0.7905 - precision: 0.7768 - recall: 0.8143

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4351 - acc: 0.7971 - precision: 0.7899 - recall: 0.8086

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4169 - acc: 0.8096 - precision: 0.7997 - recall: 0.8254

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.3912 - acc: 0.8227 - precision: 0.8128 - recall: 0.8376

88/88 [==============================] - 1s 3ms/step - loss: 0.5547 - acc: 0.7407 - precision: 0.7235 - recall: 0.7822

Model: "sequential_100"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_300 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_300 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_301 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_301 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_302 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_302 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_100 (Flatten)       (None, 512)               0         

                                                                 

 dense_200 (Dense)           (None, 512)               262656    

                                                                 

 dropout_98 (Dropout)        (None, 512)               0         

                                                                 

 dense_201 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5909 - acc: 0.6789 - precision: 0.6925 - recall: 0.7137

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5472 - acc: 0.7321 - precision: 0.7267 - recall: 0.7377

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5347 - acc: 0.7395 - precision: 0.7326 - recall: 0.7481

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5286 - acc: 0.7425 - precision: 0.7342 - recall: 0.7542

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5143 - acc: 0.7486 - precision: 0.7425 - recall: 0.7553

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5024 - acc: 0.7566 - precision: 0.7488 - recall: 0.7668

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4942 - acc: 0.7636 - precision: 0.7559 - recall: 0.7733

Epoch 8/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4833 - acc: 0.7686 - precision: 0.7590 - recall: 0.7819

Epoch 9/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4626 - acc: 0.7843 - precision: 0.7761 - recall: 0.7945

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4504 - acc: 0.7857 - precision: 0.7803 - recall: 0.7909

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4152 - acc: 0.8100 - precision: 0.8061 - recall: 0.8125

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.3998 - acc: 0.8159 - precision: 0.8091 - recall: 0.8233

88/88 [==============================] - 1s 3ms/step - loss: 0.5374 - acc: 0.7514 - precision: 0.7325 - recall: 0.8037

Model: "sequential_101"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_303 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_303 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_304 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_304 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_305 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_305 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_101 (Flatten)       (None, 512)               0         

                                                                 

 dense_202 (Dense)           (None, 512)               262656    

                                                                 

 dropout_99 (Dropout)        (None, 512)               0         

                                                                 

 dense_203 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5857 - acc: 0.6948 - precision: 0.7082 - recall: 0.7377

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5490 - acc: 0.7225 - precision: 0.7254 - recall: 0.7243

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5360 - acc: 0.7418 - precision: 0.7396 - recall: 0.7537

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5276 - acc: 0.7459 - precision: 0.7380 - recall: 0.7696

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5186 - acc: 0.7470 - precision: 0.7445 - recall: 0.7590

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5061 - acc: 0.7607 - precision: 0.7545 - recall: 0.7795

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4967 - acc: 0.7645 - precision: 0.7581 - recall: 0.7831

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4857 - acc: 0.7730 - precision: 0.7686 - recall: 0.7873

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4742 - acc: 0.7807 - precision: 0.7753 - recall: 0.7962

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4596 - acc: 0.7882 - precision: 0.7787 - recall: 0.8107

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4344 - acc: 0.7952 - precision: 0.7872 - recall: 0.8142

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4163 - acc: 0.8050 - precision: 0.7990 - recall: 0.8199

88/88 [==============================] - 1s 3ms/step - loss: 0.5367 - acc: 0.7450 - precision: 0.7191 - recall: 0.7882

Model: "sequential_102"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_306 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_306 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_307 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_307 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_308 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_308 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_102 (Flatten)       (None, 512)               0         

                                                                 

 dense_204 (Dense)           (None, 512)               262656    

                                                                 

 dropout_100 (Dropout)       (None, 512)               0         

                                                                 

 dense_205 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 4ms/step - loss: 0.5855 - acc: 0.6945 - precision: 0.6985 - recall: 0.7359

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5467 - acc: 0.7295 - precision: 0.7235 - recall: 0.7413

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5346 - acc: 0.7373 - precision: 0.7310 - recall: 0.7496

Epoch 4/12

175/175 [==============================] - 1s 6ms/step - loss: 0.5176 - acc: 0.7495 - precision: 0.7412 - recall: 0.7653

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5068 - acc: 0.7589 - precision: 0.7511 - recall: 0.7732

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4928 - acc: 0.7634 - precision: 0.7526 - recall: 0.7835

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4819 - acc: 0.7743 - precision: 0.7622 - recall: 0.7961

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4647 - acc: 0.7832 - precision: 0.7755 - recall: 0.7961

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4488 - acc: 0.7911 - precision: 0.7805 - recall: 0.8089

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4216 - acc: 0.8075 - precision: 0.7990 - recall: 0.8208

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4046 - acc: 0.8105 - precision: 0.7986 - recall: 0.8297

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3734 - acc: 0.8302 - precision: 0.8222 - recall: 0.8419

88/88 [==============================] - 1s 3ms/step - loss: 0.5961 - acc: 0.7318 - precision: 0.7070 - recall: 0.7950

Model: "sequential_103"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_309 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_309 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_310 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_310 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_311 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_311 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_103 (Flatten)       (None, 512)               0         

                                                                 

 dense_206 (Dense)           (None, 512)               262656    

                                                                 

 dropout_101 (Dropout)       (None, 512)               0         

                                                                 

 dense_207 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5945 - acc: 0.6825 - precision: 0.6886 - recall: 0.7220

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5484 - acc: 0.7287 - precision: 0.7245 - recall: 0.7316

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5345 - acc: 0.7402 - precision: 0.7334 - recall: 0.7485

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5282 - acc: 0.7412 - precision: 0.7306 - recall: 0.7582

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5134 - acc: 0.7521 - precision: 0.7453 - recall: 0.7603

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5005 - acc: 0.7607 - precision: 0.7524 - recall: 0.7719

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4914 - acc: 0.7677 - precision: 0.7604 - recall: 0.7765

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4767 - acc: 0.7711 - precision: 0.7624 - recall: 0.7827

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4628 - acc: 0.7830 - precision: 0.7755 - recall: 0.7920

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4408 - acc: 0.8000 - precision: 0.7920 - recall: 0.8096

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4092 - acc: 0.8082 - precision: 0.8022 - recall: 0.8143

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3937 - acc: 0.8184 - precision: 0.8126 - recall: 0.8240

88/88 [==============================] - 1s 3ms/step - loss: 0.5422 - acc: 0.7554 - precision: 0.7390 - recall: 0.8008

Model: "sequential_104"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_312 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_312 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_313 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_313 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_314 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_314 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_104 (Flatten)       (None, 512)               0         

                                                                 

 dense_208 (Dense)           (None, 512)               262656    

                                                                 

 dropout_102 (Dropout)       (None, 512)               0         

                                                                 

 dense_209 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5771 - acc: 0.6986 - precision: 0.7138 - recall: 0.7365

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5479 - acc: 0.7318 - precision: 0.7313 - recall: 0.7406

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5354 - acc: 0.7423 - precision: 0.7395 - recall: 0.7555

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5243 - acc: 0.7475 - precision: 0.7396 - recall: 0.7711

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5144 - acc: 0.7529 - precision: 0.7488 - recall: 0.7679

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5001 - acc: 0.7643 - precision: 0.7563 - recall: 0.7863

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4899 - acc: 0.7693 - precision: 0.7625 - recall: 0.7884

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4796 - acc: 0.7750 - precision: 0.7689 - recall: 0.7923

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4617 - acc: 0.7904 - precision: 0.7850 - recall: 0.8050

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4396 - acc: 0.7945 - precision: 0.7873 - recall: 0.8121

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4235 - acc: 0.8071 - precision: 0.7990 - recall: 0.8255

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4027 - acc: 0.8184 - precision: 0.8170 - recall: 0.8248

88/88 [==============================] - 1s 3ms/step - loss: 0.5416 - acc: 0.7514 - precision: 0.7348 - recall: 0.7722

Model: "sequential_105"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_315 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_315 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_316 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_316 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_317 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_317 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_105 (Flatten)       (None, 512)               0         

                                                                 

 dense_210 (Dense)           (None, 512)               262656    

                                                                 

 dropout_103 (Dropout)       (None, 512)               0         

                                                                 

 dense_211 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5861 - acc: 0.6905 - precision: 0.6994 - recall: 0.7321

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5490 - acc: 0.7271 - precision: 0.7207 - recall: 0.7403

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5395 - acc: 0.7377 - precision: 0.7330 - recall: 0.7463

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5246 - acc: 0.7455 - precision: 0.7378 - recall: 0.7603

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5114 - acc: 0.7595 - precision: 0.7510 - recall: 0.7750

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5010 - acc: 0.7552 - precision: 0.7438 - recall: 0.7771

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4874 - acc: 0.7641 - precision: 0.7547 - recall: 0.7814

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4774 - acc: 0.7739 - precision: 0.7628 - recall: 0.7939

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4620 - acc: 0.7821 - precision: 0.7728 - recall: 0.7982

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4424 - acc: 0.7946 - precision: 0.7839 - recall: 0.8125

Epoch 11/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4212 - acc: 0.8050 - precision: 0.7915 - recall: 0.8272

Epoch 12/12

175/175 [==============================] - 1s 6ms/step - loss: 0.4033 - acc: 0.8141 - precision: 0.8043 - recall: 0.8293

88/88 [==============================] - 1s 3ms/step - loss: 0.5558 - acc: 0.7379 - precision: 0.7067 - recall: 0.8164

Model: "sequential_106"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_318 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_318 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_319 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_319 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_320 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_320 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_106 (Flatten)       (None, 512)               0         

                                                                 

 dense_212 (Dense)           (None, 512)               262656    

                                                                 

 dropout_104 (Dropout)       (None, 512)               0         

                                                                 

 dense_213 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5912 - acc: 0.6802 - precision: 0.6895 - recall: 0.7213

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5433 - acc: 0.7337 - precision: 0.7285 - recall: 0.7388

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5349 - acc: 0.7361 - precision: 0.7290 - recall: 0.7452

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5291 - acc: 0.7396 - precision: 0.7305 - recall: 0.7531

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5114 - acc: 0.7545 - precision: 0.7486 - recall: 0.7607

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4990 - acc: 0.7616 - precision: 0.7510 - recall: 0.7773

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4918 - acc: 0.7688 - precision: 0.7613 - recall: 0.7780

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4770 - acc: 0.7693 - precision: 0.7608 - recall: 0.7805

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4567 - acc: 0.7880 - precision: 0.7797 - recall: 0.7985

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4405 - acc: 0.7973 - precision: 0.7900 - recall: 0.8057

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4114 - acc: 0.8095 - precision: 0.8029 - recall: 0.8165

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.3912 - acc: 0.8243 - precision: 0.8166 - recall: 0.8330

88/88 [==============================] - 1s 3ms/step - loss: 0.5493 - acc: 0.7514 - precision: 0.7526 - recall: 0.7600

Model: "sequential_107"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_321 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_321 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_322 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_322 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_323 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_323 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_107 (Flatten)       (None, 512)               0         

                                                                 

 dense_214 (Dense)           (None, 512)               262656    

                                                                 

 dropout_105 (Dropout)       (None, 512)               0         

                                                                 

 dense_215 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 4s 4ms/step - loss: 0.5835 - acc: 0.6989 - precision: 0.7162 - recall: 0.7273

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5477 - acc: 0.7280 - precision: 0.7311 - recall: 0.7293

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5353 - acc: 0.7411 - precision: 0.7358 - recall: 0.7597

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5292 - acc: 0.7455 - precision: 0.7393 - recall: 0.7657

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5161 - acc: 0.7484 - precision: 0.7446 - recall: 0.7633

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5054 - acc: 0.7625 - precision: 0.7565 - recall: 0.7806

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4948 - acc: 0.7691 - precision: 0.7624 - recall: 0.7880

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4841 - acc: 0.7771 - precision: 0.7704 - recall: 0.7955

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4761 - acc: 0.7823 - precision: 0.7779 - recall: 0.7958

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4576 - acc: 0.7871 - precision: 0.7804 - recall: 0.8047

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4371 - acc: 0.7993 - precision: 0.7900 - recall: 0.8202

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4198 - acc: 0.8070 - precision: 0.8020 - recall: 0.8199

88/88 [==============================] - 1s 4ms/step - loss: 0.5361 - acc: 0.7504 - precision: 0.7320 - recall: 0.7751

Model: "sequential_108"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_324 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_324 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_325 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_325 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_326 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_326 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_108 (Flatten)       (None, 512)               0         

                                                                 

 dense_216 (Dense)           (None, 512)               262656    

                                                                 

 dropout_106 (Dropout)       (None, 512)               0         

                                                                 

 dense_217 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5878 - acc: 0.6880 - precision: 0.6984 - recall: 0.7275

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5495 - acc: 0.7232 - precision: 0.7141 - recall: 0.7428

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5389 - acc: 0.7350 - precision: 0.7290 - recall: 0.7467

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5242 - acc: 0.7450 - precision: 0.7348 - recall: 0.7653

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5101 - acc: 0.7625 - precision: 0.7541 - recall: 0.7778

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4964 - acc: 0.7607 - precision: 0.7491 - recall: 0.7828

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4839 - acc: 0.7739 - precision: 0.7670 - recall: 0.7857

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4734 - acc: 0.7770 - precision: 0.7684 - recall: 0.7918

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4552 - acc: 0.7891 - precision: 0.7789 - recall: 0.8064

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4393 - acc: 0.7973 - precision: 0.7846 - recall: 0.8186

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4208 - acc: 0.8027 - precision: 0.7928 - recall: 0.8186

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.3915 - acc: 0.8152 - precision: 0.8060 - recall: 0.8293

88/88 [==============================] - 1s 3ms/step - loss: 0.5667 - acc: 0.7368 - precision: 0.7090 - recall: 0.8064

Model: "sequential_109"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_327 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_327 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_328 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_328 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_329 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_329 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_109 (Flatten)       (None, 512)               0         

                                                                 

 dense_218 (Dense)           (None, 512)               262656    

                                                                 

 dropout_107 (Dropout)       (None, 512)               0         

                                                                 

 dense_219 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 7ms/step - loss: 0.5916 - acc: 0.6837 - precision: 0.6915 - recall: 0.7232

Epoch 2/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5451 - acc: 0.7300 - precision: 0.7220 - recall: 0.7413

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5368 - acc: 0.7382 - precision: 0.7296 - recall: 0.7506

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5280 - acc: 0.7396 - precision: 0.7297 - recall: 0.7549

Epoch 5/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5135 - acc: 0.7491 - precision: 0.7387 - recall: 0.7650

Epoch 6/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5027 - acc: 0.7584 - precision: 0.7493 - recall: 0.7711

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4922 - acc: 0.7671 - precision: 0.7600 - recall: 0.7758

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7704 - precision: 0.7600 - recall: 0.7852

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4654 - acc: 0.7854 - precision: 0.7739 - recall: 0.8017

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4448 - acc: 0.7920 - precision: 0.7820 - recall: 0.8053

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4147 - acc: 0.8107 - precision: 0.8017 - recall: 0.8219

Epoch 12/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4021 - acc: 0.8161 - precision: 0.8098 - recall: 0.8226

88/88 [==============================] - 1s 3ms/step - loss: 0.5471 - acc: 0.7436 - precision: 0.7396 - recall: 0.7635

Model: "sequential_110"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_330 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_330 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_331 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_331 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_332 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_332 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_110 (Flatten)       (None, 512)               0         

                                                                 

 dense_220 (Dense)           (None, 512)               262656    

                                                                 

 dropout_108 (Dropout)       (None, 512)               0         

                                                                 

 dense_221 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5752 - acc: 0.7077 - precision: 0.7172 - recall: 0.7356

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5456 - acc: 0.7312 - precision: 0.7312 - recall: 0.7392

Epoch 3/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5329 - acc: 0.7446 - precision: 0.7404 - recall: 0.7608

Epoch 4/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5242 - acc: 0.7504 - precision: 0.7435 - recall: 0.7714

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5123 - acc: 0.7554 - precision: 0.7505 - recall: 0.7718

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4966 - acc: 0.7675 - precision: 0.7595 - recall: 0.7891

Epoch 7/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4943 - acc: 0.7684 - precision: 0.7617 - recall: 0.7873

Epoch 8/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4812 - acc: 0.7743 - precision: 0.7675 - recall: 0.7930

Epoch 9/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4671 - acc: 0.7839 - precision: 0.7779 - recall: 0.8004

Epoch 10/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4500 - acc: 0.7880 - precision: 0.7788 - recall: 0.8100

Epoch 11/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4232 - acc: 0.8057 - precision: 0.7976 - recall: 0.8241

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4089 - acc: 0.8130 - precision: 0.8029 - recall: 0.8344

88/88 [==============================] - 1s 4ms/step - loss: 0.5401 - acc: 0.7550 - precision: 0.7331 - recall: 0.7875

Model: "sequential_111"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_333 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_333 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_334 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_334 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_335 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_335 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_111 (Flatten)       (None, 512)               0         

                                                                 

 dense_222 (Dense)           (None, 512)               262656    

                                                                 

 dropout_109 (Dropout)       (None, 512)               0         

                                                                 

 dense_223 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

175/175 [==============================] - 3s 5ms/step - loss: 0.5858 - acc: 0.6959 - precision: 0.7045 - recall: 0.7354

Epoch 2/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5497 - acc: 0.7254 - precision: 0.7189 - recall: 0.7385

Epoch 3/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5332 - acc: 0.7380 - precision: 0.7314 - recall: 0.7510

Epoch 4/12

175/175 [==============================] - 1s 5ms/step - loss: 0.5205 - acc: 0.7504 - precision: 0.7408 - recall: 0.7689

Epoch 5/12

175/175 [==============================] - 1s 4ms/step - loss: 0.5089 - acc: 0.7623 - precision: 0.7556 - recall: 0.7742

Epoch 6/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4997 - acc: 0.7580 - precision: 0.7505 - recall: 0.7717

Epoch 7/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4874 - acc: 0.7700 - precision: 0.7617 - recall: 0.7846

Epoch 8/12

175/175 [==============================] - 1s 5ms/step - loss: 0.4757 - acc: 0.7777 - precision: 0.7684 - recall: 0.7939

Epoch 9/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4591 - acc: 0.7800 - precision: 0.7707 - recall: 0.7961

Epoch 10/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4428 - acc: 0.7950 - precision: 0.7880 - recall: 0.8061

Epoch 11/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4297 - acc: 0.7995 - precision: 0.7883 - recall: 0.8179

Epoch 12/12

175/175 [==============================] - 1s 4ms/step - loss: 0.4050 - acc: 0.8125 - precision: 0.8020 - recall: 0.8290

88/88 [==============================] - 1s 3ms/step - loss: 0.5528 - acc: 0.7382 - precision: 0.7350 - recall: 0.7480

Model: "sequential_112"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_336 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_336 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_337 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_337 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_338 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_338 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_112 (Flatten)       (None, 512)               0         

                                                                 

 dense_224 (Dense)           (None, 512)               262656    

                                                                 

 dropout_110 (Dropout)       (None, 512)               0         

                                                                 

 dense_225 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

263/263 [==============================] - 4s 6ms/step - loss: 0.5772 - acc: 0.6990 - precision: 0.7061 - recall: 0.7163

Epoch 2/12

263/263 [==============================] - 1s 5ms/step - loss: 0.5409 - acc: 0.7371 - precision: 0.7325 - recall: 0.7471

Epoch 3/12

263/263 [==============================] - 2s 6ms/step - loss: 0.5257 - acc: 0.7470 - precision: 0.7356 - recall: 0.7712

Epoch 4/12

263/263 [==============================] - 1s 5ms/step - loss: 0.5145 - acc: 0.7573 - precision: 0.7484 - recall: 0.7750

Epoch 5/12

263/263 [==============================] - 2s 7ms/step - loss: 0.5011 - acc: 0.7585 - precision: 0.7516 - recall: 0.7721

Epoch 6/12

263/263 [==============================] - 1s 5ms/step - loss: 0.4926 - acc: 0.7671 - precision: 0.7584 - recall: 0.7840

Epoch 7/12

263/263 [==============================] - 1s 5ms/step - loss: 0.4748 - acc: 0.7790 - precision: 0.7714 - recall: 0.7931

Epoch 8/12

263/263 [==============================] - 1s 5ms/step - loss: 0.4622 - acc: 0.7811 - precision: 0.7732 - recall: 0.7955

Epoch 9/12

263/263 [==============================] - 1s 5ms/step - loss: 0.4447 - acc: 0.7918 - precision: 0.7815 - recall: 0.8100

Epoch 10/12

263/263 [==============================] - 1s 5ms/step - loss: 0.4168 - acc: 0.8082 - precision: 0.7996 - recall: 0.8226

Epoch 11/12

263/263 [==============================] - 1s 5ms/step - loss: 0.3843 - acc: 0.8267 - precision: 0.8186 - recall: 0.8393

Epoch 12/12

263/263 [==============================] - 1s 5ms/step - loss: 0.3573 - acc: 0.8399 - precision: 0.8310 - recall: 0.8533

Best: 0.748214 using {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}

0.745714 (0.005541) with: {'activation': 'relu', 'learning_rate': 0.0001, 'optimizer': 'adam'}

0.746548 (0.003515) with: {'activation': 'relu', 'learning_rate': 0.0001, 'optimizer': 'sgd'}

0.745476 (0.008146) with: {'activation': 'relu', 'learning_rate': 0.001, 'optimizer': 'adam'}

0.744524 (0.009869) with: {'activation': 'relu', 'learning_rate': 0.001, 'optimizer': 'sgd'}

0.741310 (0.006290) with: {'activation': 'relu', 'learning_rate': 0.01, 'optimizer': 'adam'}

0.737143 (0.005353) with: {'activation': 'relu', 'learning_rate': 0.01, 'optimizer': 'sgd'}

0.743095 (0.004960) with: {'activation': 'LeakyReLU', 'learning_rate': 0.0001, 'optimizer': 'adam'}

0.743571 (0.004296) with: {'activation': 'LeakyReLU', 'learning_rate': 0.0001, 'optimizer': 'sgd'}

0.742738 (0.008177) with: {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'adam'}

0.748214 (0.007497) with: {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}

0.746190 (0.006665) with: {'activation': 'LeakyReLU', 'learning_rate': 0.01, 'optimizer': 'adam'}

0.745595 (0.007001) with: {'activation': 'LeakyReLU', 'learning_rate': 0.01, 'optimizer': 'sgd'}

The Best parameters returned after Grid Search: 0.748214 using {'activation': 'LeakyReLU', 'learning_rate': 0.001, 'optimizer': 'sgd'}

Lets build a model with these parameters and check its performance.

In [ ]:
model_5 = create_model(optimizer='sgd', hidden_units=512, dropout_rate=0.5,
                 activation='LeakyReLU', learning_rate=0.001,
                 weight_init='he_normal')
history_5 = fit_model(model_5, NUM_OF_EPOCHS)
evaluate_model_perf(history_5, model_5, 'Model_Tuning_with_GridSearch')
Model: "sequential_114"

_________________________________________________________________

 Layer (type)                Output Shape              Param #   

=================================================================

 conv2d_342 (Conv2D)         (None, 30, 30, 32)        320       

                                                                 

 max_pooling2d_342 (MaxPooli  (None, 15, 15, 32)       0         

 ng2D)                                                           

                                                                 

 conv2d_343 (Conv2D)         (None, 13, 13, 64)        18496     

                                                                 

 max_pooling2d_343 (MaxPooli  (None, 6, 6, 64)         0         

 ng2D)                                                           

                                                                 

 conv2d_344 (Conv2D)         (None, 4, 4, 128)         73856     

                                                                 

 max_pooling2d_344 (MaxPooli  (None, 2, 2, 128)        0         

 ng2D)                                                           

                                                                 

 flatten_114 (Flatten)       (None, 512)               0         

                                                                 

 dense_228 (Dense)           (None, 512)               262656    

                                                                 

 dropout_112 (Dropout)       (None, 512)               0         

                                                                 

 dense_229 (Dense)           (None, 1)                 513       

                                                                 

=================================================================

Total params: 355,841

Trainable params: 355,841

Non-trainable params: 0

_________________________________________________________________

Epoch 1/12

1049/1050 [============================>.] - ETA: 0s - loss: 0.6027 - acc: 0.6793 - precision: 0.7554 - recall: 0.7678

Epoch 1: val_acc did not improve from 0.74778

1050/1050 [==============================] - 18s 15ms/step - loss: 0.6025 - acc: 0.6794 - precision: 0.7554 - recall: 0.7679 - val_loss: 0.5732 - val_acc: 0.6967 - val_precision: 0.6791 - val_recall: 0.7456 - lr: 0.0010

Epoch 2/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5697 - acc: 0.7139 - precision: 0.7139 - recall: 0.7144

Epoch 2: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5701 - acc: 0.7136 - precision: 0.7132 - recall: 0.7145 - val_loss: 0.5647 - val_acc: 0.7139 - val_precision: 0.6811 - val_recall: 0.8044 - lr: 0.0010

Epoch 3/12

1050/1050 [==============================] - ETA: 0s - loss: 0.5615 - acc: 0.7205 - precision: 0.7158 - recall: 0.7314

Epoch 3: val_acc did not improve from 0.74778

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5615 - acc: 0.7205 - precision: 0.7158 - recall: 0.7314 - val_loss: 0.5566 - val_acc: 0.7200 - val_precision: 0.6930 - val_recall: 0.7900 - lr: 0.0010

Epoch 4/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.5566 - acc: 0.7217 - precision: 0.7188 - recall: 0.7282

Epoch 4: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 14ms/step - loss: 0.5567 - acc: 0.7215 - precision: 0.7189 - recall: 0.7276 - val_loss: 0.5667 - val_acc: 0.7167 - val_precision: 0.7716 - val_recall: 0.6156 - lr: 0.0010

Epoch 5/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5582 - acc: 0.7244 - precision: 0.7212 - recall: 0.7314

Epoch 5: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5586 - acc: 0.7240 - precision: 0.7207 - recall: 0.7317 - val_loss: 0.5400 - val_acc: 0.7350 - val_precision: 0.7291 - val_recall: 0.7478 - lr: 0.0010

Epoch 6/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5530 - acc: 0.7241 - precision: 0.7247 - recall: 0.7232

Epoch 6: val_acc did not improve from 0.74778

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5530 - acc: 0.7242 - precision: 0.7246 - recall: 0.7231 - val_loss: 0.5444 - val_acc: 0.7256 - val_precision: 0.7350 - val_recall: 0.7056 - lr: 0.0010

Epoch 7/12

1042/1050 [============================>.] - ETA: 0s - loss: 0.5482 - acc: 0.7241 - precision: 0.7236 - recall: 0.7247

Epoch 7: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 14ms/step - loss: 0.5477 - acc: 0.7242 - precision: 0.7241 - recall: 0.7243 - val_loss: 0.5274 - val_acc: 0.7344 - val_precision: 0.7212 - val_recall: 0.7644 - lr: 0.0010

Epoch 8/12

1045/1050 [============================>.] - ETA: 0s - loss: 0.5435 - acc: 0.7300 - precision: 0.7284 - recall: 0.7345

Epoch 8: val_acc did not improve from 0.74778

1050/1050 [==============================] - 16s 15ms/step - loss: 0.5440 - acc: 0.7296 - precision: 0.7279 - recall: 0.7336 - val_loss: 0.5821 - val_acc: 0.6939 - val_precision: 0.8099 - val_recall: 0.5067 - lr: 0.0010

Epoch 9/12

1048/1050 [============================>.] - ETA: 0s - loss: 0.5457 - acc: 0.7307 - precision: 0.7305 - recall: 0.7312

Epoch 9: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 15ms/step - loss: 0.5457 - acc: 0.7305 - precision: 0.7301 - recall: 0.7312 - val_loss: 0.5379 - val_acc: 0.7278 - val_precision: 0.7628 - val_recall: 0.6611 - lr: 0.0010

Epoch 10/12

1046/1050 [============================>.] - ETA: 0s - loss: 0.5417 - acc: 0.7328 - precision: 0.7332 - recall: 0.7304

Epoch 10: val_acc did not improve from 0.74778

1050/1050 [==============================] - 16s 16ms/step - loss: 0.5418 - acc: 0.7326 - precision: 0.7336 - recall: 0.7305 - val_loss: 0.5494 - val_acc: 0.7289 - val_precision: 0.6843 - val_recall: 0.8500 - lr: 0.0010

Epoch 11/12

1043/1050 [============================>.] - ETA: 0s - loss: 0.5392 - acc: 0.7373 - precision: 0.7349 - recall: 0.7416

Epoch 11: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 14ms/step - loss: 0.5396 - acc: 0.7370 - precision: 0.7348 - recall: 0.7417 - val_loss: 0.5451 - val_acc: 0.7178 - val_precision: 0.6888 - val_recall: 0.7944 - lr: 0.0010

Epoch 12/12

1047/1050 [============================>.] - ETA: 0s - loss: 0.5405 - acc: 0.7328 - precision: 0.7332 - recall: 0.7329

Epoch 12: val_acc did not improve from 0.74778

1050/1050 [==============================] - 15s 14ms/step - loss: 0.5404 - acc: 0.7329 - precision: 0.7329 - recall: 0.7329 - val_loss: 0.5609 - val_acc: 0.7378 - val_precision: 0.7616 - val_recall: 0.6922 - lr: 0.0010

57/57 [==============================] - 0s 2ms/step







--------------------------------------------------------------------------------

Classification Matrix

--------------------------------------------------------------------------------

                     precision    recall  f1-score   support



   Normal (Class 0)       0.76      0.74      0.75       900

Pneumonia (Class 1)       0.75      0.77      0.76       900



           accuracy                           0.76      1800

          macro avg       0.76      0.76      0.76      1800

       weighted avg       0.76      0.76      0.76      1800



--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>

Observation

Even after using Hyperparameter tuning with Grid Search, there is not much improvement seen in CNN model's performance. The accuracy and precision is still around 76%, almost same as Base CNN Model performance.

If any two models are developed to perform similar tasks, then generalised knowledge can be shared between them. This approach to machine learning development reduces the resources and amount of labelled data required to train new models. It is becoming an important part of the evolution of machine learning and is increasingly used as a technique within the development process.

Transfer learning for machine learning is when elements of a pre-trained model are reused in a new machine learning model. Transfer models can be tried to compare model performance.

Limitations of Grid Search

  1. Computation power and time:

The main problem with grid search is that it takes a lot of time and computing power. Since it checks every possible combination of settings, it can mean evaluating many models, especially when there are a lot of settings to play with and a wide range of values for each one. This can make finding the best settings drag on and on, making it too slow for some models and data.

  1. Limited and Biased Search:

When choosing the search space for Grid Search, data scientists usually reflect on their previous successful hyperparameter tuning jobs and tend to repeatedly choose the same parameters and ranges for different projects. As a result, Grid Search inherits the users’ bias in their perception of the optimal search space for the best hyperparameters. On the other hand, expanding the search space further will exponentially increase the processing time for Grid Search. Ex: What if the best hyperparameters for the model are not even in your search space? What if the best max_depth for that XGBoost model is 9, but you searched over [4, 5, 6, 7]?

  1. Curse of dimensionality:

One of the major drawbacks of grid search is that when it comes to dimensionality, it suffers when the number of hyperparameters grows exponentially. With as few as four parameters this problem can become impractical, because the number of evaluations required for this strategy increases exponentially with each additional parameter, due to the curse of dimensionality.

Step 2: Apply Transfer Learning model for classification¶

Source Data

Before feeding the images into the models, we conducted the following preprocessing steps:

  • Image resizing to a common size of 32x32 pixels.
  • Data augmentation techniques, including rotation, horizontal flip, and brightness adjustments, to increase the dataset size and improve model generalization.

Model Architectures

We experimented with five pre-trained deep learning models, each loaded with pre-trained weights from ImageNet:

ResNet50

ResNet50 is a convolutional neural network (CNN) architecture with 50 layers. It is known for its deep structure and skip connections, which help alleviate the vanishing gradient problem. ResNet50 has been widely used in image classification tasks.

• Accuracy: 73%

• AUC: 73

• Precision (Class 0/1): 0.69 / 0.79

• Recall (Class 0/1): 0.84 / 0.62

• F1-score (Class 0/1): 0.76 / 0.70

ResNet101

ResNet101 is an extension of ResNet50, with even deeper architecture, consisting of 101 layers. It offers improved feature extraction capabilities and is known for its excellent performance on various image-related tasks.

• Accuracy: 52%

• AUC: 51.61

• Precision (Class 0/1): 0.51 / 0.61

• Recall (Class 0/1): 0.94 / 0.09

• F1-score (Class 0/1): 0.66 / 0.16

MobileNet

MobileNet is designed for efficient inference on mobile and embedded devices. It uses depthwise separable convolutions to reduce computational complexity while maintaining good performance. MobileNet is lightweight and suitable for resource-constrained environments.

• Accuracy: 78%

• AUC: 77.56

• Precision (Class 0/1): 0.81 / 0.75

• Recall (Class 0/1): 0.73 / 0.83

• F1-score (Class 0/1): 0.76 / 0.79

EfficientNetB0

EfficientNetB0 is part of the EfficientNet family, known for its superior efficiency and performance. It employs a compound scaling method to balance network depth, width, and resolution, resulting in models that achieve state-of-the-art results with fewer parameters.

• Accuracy: 74%

• AUC: 74.11

• Precision (Class 0/1): 0.81 / 0.70

• Recall (Class 0/1): 0.63 / 0.86

• F1-score (Class 0/1): 0.71 / 0.77

VGG19

VGG19 is a variant of the VGG (Visual Geometry Group) architecture. It has 19 layers with small (3x3) convolutional filters, making it deeper than the original VGG15. VGG networks are known for their simplicity and effectiveness in image classification tasks.

• Accuracy: 74%

• AUC: 50

• Precision (Class 0/1): 0.81 / 0.70

• Recall (Class 0/1): 0.63 / 0.86

• F1-score (Class 0/1): 0.71 / 0.77

Model Comparison

  • Accuracy: MobileNet achieved the highest accuracy at 78%, followed closely by EfficientNetB0 and VGG19, both at 74%. ResNet50 achieved 73% accuracy, while ResNet101 lagged behind with 52% accuracy.

  • AUC (Area Under the ROC Curve): MobileNet and EfficientNetB0 show the highest AUC scores of 77.56 and 74.11, respectively, indicating strong model performance. ResNet50 follows with an AUC of 73. ResNet101 and VGG19 perform less optimally, with AUC scores of 51.61 and 50, respectively.

  • Precision and Recall: MobileNet and EfficientNetB0 exhibit a balance between precision and recall for both classes, making them suitable for real-world deployment. ResNet50 shows competitive recall for Class 0 (normal) but relatively lower precision for Class 1 (pneumonia). ResNet101 has very high recall for Class 0 but significantly lower recall for Class 1. VGG19 has relatively high precision but lower recall for both classes.

  • F1-Score: MobileNet and EfficientNetB0 achieve the highest F1-scores for both Class 0 and Class 1, demonstrating their effectiveness in classifying both normal and pneumonia cases. ResNet50 shows balanced F1-scores but slightly lower performance compared to MobileNet and EfficientNetB0. ResNet101 and VGG19 exhibit lower F1-scores overall, indicating suboptimal performance.

Conclusion In conclusion, based on the comprehensive analysis of accuracy, AUC, precision, recall, and F1-score, MobileNet and EfficientNetB0 emerge as the top-performing models for pneumonia detection from chest X-ray images.

MobileNet achieves the highest accuracy and AUC, indicating excellent overall performance.

EfficientNetB0 closely follows with competitive metrics, including precision and recall.

These models offer a balance between correctly classifying normal and pneumonia cases, which is crucial for medical diagnosis. While both models perform exceptionally well, the choice between MobileNet and EfficientNetB0 could depend on factors like computational resources and deployment constraints. MobileNet might be preferable for resource-constrained environments, while EfficientNetB0 could be chosen for situations where computational resources are more abundant.

Training Strategy

The dataset was split into training (70%), validation (15%), and test (15%) sets. The models were trained using categorical cross-entropy loss and optimized with the Adam optimizer. An early stopping mechanism was implemented to prevent overfitting, and a learning rate reduction on a plateau was employed.

In [ ]:
def read_and_resize_images_rgb(final_df):
    resized_rgb_images = []
    boxes = []
    for i in range(len(final_df)):
        patient_id = final_df['patientId'].iloc[i]  # Access 'patientId' column
        target = final_df['Target'].iloc[i]        # Access 'Target' column
        dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH, '%s.dcm' % patient_id))
        img = dicom_data.pixel_array

        # Resize image to 32x32
        img = cv2.resize(img, (32, 32))

        # Convert grayscale image to RGB format
        img_rgb = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)

        resized_rgb_images.append(img_rgb)
        boxes.append(np.array(target, dtype=np.float32))
    return np.array(resized_rgb_images), np.array(boxes)
In [ ]:
NUM_OF_EPOCHS = 12
FONT_SIZE = 10

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score, precision_score, recall_score, f1_score

model_comparision_list = []

def evaluate_model_perf_tl(history, model, model_descr):
    if 'acc' in history.history:
        accuracy_key = 'acc'
    elif 'accuracy' in history.history:
        accuracy_key = 'accuracy'
    else:
        raise ValueError("Neither 'acc' nor 'accuracy' found in history.history.")

    if 'val_acc' in history.history:
        val_accuracy_key = 'val_acc'
    elif 'val_accuracy' in history.history:
        val_accuracy_key = 'val_accuracy'
    else:
        raise ValueError("Neither 'val_acc' nor 'val_accuracy' found in history.history.")

    epochs = [i for i in range(len(history.history[accuracy_key]))]
    fig = plt.figure(figsize=(16, 5))

    plt.subplot(1, 3, 1)
    plt.plot(epochs, history.history[accuracy_key], marker='o', color='orange', label='Training Accuracy')
    plt.plot(epochs, history.history[val_accuracy_key], marker='o', color='turquoise', label='Validation Accuracy')
    plt.title('Training & Validation Accuracy')
    plt.legend(fontsize=FONT_SIZE)
    plt.xticks(fontsize=FONT_SIZE)
    plt.yticks(fontsize=FONT_SIZE)
    plt.xlabel("Epochs", size=FONT_SIZE)
    plt.ylabel("Accuracy", size=FONT_SIZE)

    plt.subplot(1, 3, 2)
    plt.plot(epochs, history.history['loss'], marker='o', color='orange', label='Training Loss')
    plt.plot(epochs, history.history['val_loss'], marker='o', color='turquoise', label='Validation Loss')
    plt.title('Testing Accuracy & Loss')
    plt.xticks(fontsize=FONT_SIZE)
    plt.yticks(fontsize=FONT_SIZE)
    plt.legend(fontsize=FONT_SIZE)
    plt.xlabel("Epochs", size=FONT_SIZE)
    plt.ylabel("Training & Validation Loss", size=FONT_SIZE)

    # Calculate y_pred based on the validation set
    y_pred = get_model_prediction(model)

    ## CONFUSION MATRIX
    plt.subplot(1, 3, 3)
    # Set up the labels for the confusion matrix
    cm = confusion_matrix(y_test, y_pred)
    labels = ['NORMAL', 'PNEUMONIA']
    ax = sns.heatmap(cm, annot=True, fmt='d', cmap="GnBu", annot_kws={"fontsize": FONT_SIZE},
                     xticklabels=labels, yticklabels=labels)
    ax.set(ylabel="True Label", xlabel="Predicted Label")
    plt.title('Confusion Matrix')
    plt.show()
    plt.tight_layout()

    print('\n\n\n')
    print('--' * 40)
    print("Classification Matrix")
    print('--' * 40)
    print(classification_report(y_test, y_pred,
                                target_names=['Normal (Class 0)', 'Pneumonia (Class 1)']))
    print('--' * 40)

    # performance_matrix list of this model
    performance_matrix = []
    performance_matrix.append(model_descr)
    performance_matrix.append(accuracy_score(y_test, y_pred) * 100)
    performance_matrix.append(precision_score(y_test, y_pred, average='macro') * 100)
    performance_matrix.append(recall_score(y_test, y_pred, average='macro') * 100)
    performance_matrix.append(f1_score(y_test, y_pred, average='macro') * 100)
    # Store the performance per model

    model_comparision_list.append(performance_matrix)
In [ ]:
# Read and resize training, validation and test images
X_train, y_train = read_and_resize_images_rgb(train)
X_val, y_val = read_and_resize_images_rgb(val)
X_test, y_test = read_and_resize_images_rgb(test)
In [ ]:
X_train = np.array(X_train) / 255
X_val = np.array(X_val) / 255
X_test = np.array(X_test) / 255
In [ ]:
# Checking the shape of train, test and validation sets
print('Shape of Training Data   X: ', X_train.shape,'Y: ',y_train.shape )
print('Shape of Testing  Data   X: ', X_test.shape,'Y: ',y_test.shape)
print('Shape of Validation Data X: ', X_val.shape,'Y: ',y_val.shape)
Shape of Training Data   X:  (8400, 32, 32, 3) Y:  (8400,)
Shape of Testing  Data   X:  (1800, 32, 32, 3) Y:  (1800,)
Shape of Validation Data X:  (1800, 32, 32, 3) Y:  (1800,)
In [ ]:
def fit_model_tl(model):
    history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
                        validation_data = valid_generator,
                        callbacks=[checkpoint,early_stopping,learning_rate_reduction],
                        batch_size=batch_size ,use_multiprocessing=True)
    return history
In [ ]:
batch_size = 8
# Establish our metrics
METRICS = ['acc',
           tf.keras.metrics.Precision(name='precision'),
           tf.keras.metrics.Recall(name='recall')]

learning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', patience = 2, verbose=1,factor=0.3, min_lr=0.000001)

early_stopping = EarlyStopping(monitor='val_loss',patience=5, restore_best_weights=True)

# Callbacks to reduce learning rate timely after monitoring a quantit
filepath="/kaggle/working/weights.hdf5"

checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')

train_datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range = 30,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.2, # Randomly zoom image
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip = True,  # randomly flip images
        vertical_flip=False)  # randomly flip images

train_datagen.fit(X_train)

test_datagen = ImageDataGenerator()

train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)

valid_generator = train_datagen.flow(X_val, y_val, batch_size=batch_size)

test_generator = test_datagen.flow(X_test, y_test, batch_size=1)

def get_model_prediction(model):
    # Predict the values from the validation dataset
    predictions = model.predict(X_test)
    # Convert predictions classes to one hot vectors
    return predictions.round().astype(int).tolist()

def fit_model(model):
    history = model.fit(train_generator, epochs = NUM_OF_EPOCHS,
                        validation_data = valid_generator,
                        callbacks=[checkpoint,early_stopping,learning_rate_reduction],
                        batch_size=batch_size ,use_multiprocessing=True)
    return history
In [ ]:
from keras.applications import ResNet50, ResNet101, InceptionV3, MobileNet, EfficientNetB0, VGG19
from keras.layers import Input, Dense, GlobalAveragePooling2D, Dropout, Lambda
from keras.models import Model
import tensorflow as tf

# Define the metrics you want to use
METRICS = ['accuracy']

def create_model(input_shape, base_model, model_name):
    # Load the base model with pre-trained weights
    base_model = base_model(input_shape=input_shape, include_top=False, weights='imagenet')
    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(512, activation='relu')(x)
    x = Dropout(0.5)(x)
    output_layer = Dense(1, activation='sigmoid')(x)

    # Create the transfer learning model
    model = Model(inputs=base_model.input, outputs=output_layer)
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=METRICS)
    model.summary()

    return model


def create_model_6():
    return create_model((32, 32, 3), MobileNet, "MobileNet")

def create_model_7():
    return create_model((32, 32, 3), EfficientNetB0, "EfficientNetB0")
In [ ]:
model_6 = create_model_6()
history_6 = fit_model_tl(model_6)
evaluate_model_perf_tl(history_6, model_6, "MobileNet")
Model: "model_2"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_3 (InputLayer)        [(None, 32, 32, 3)]       0         
                                                                 
 conv1 (Conv2D)              (None, 16, 16, 32)        864       
                                                                 
 conv1_bn (BatchNormalizatio  (None, 16, 16, 32)       128       
 n)                                                              
                                                                 
 conv1_relu (ReLU)           (None, 16, 16, 32)        0         
                                                                 
 conv_dw_1 (DepthwiseConv2D)  (None, 16, 16, 32)       288       
                                                                 
 conv_dw_1_bn (BatchNormaliz  (None, 16, 16, 32)       128       
 ation)                                                          
                                                                 
 conv_dw_1_relu (ReLU)       (None, 16, 16, 32)        0         
                                                                 
 conv_pw_1 (Conv2D)          (None, 16, 16, 64)        2048      
                                                                 
 conv_pw_1_bn (BatchNormaliz  (None, 16, 16, 64)       256       
 ation)                                                          
                                                                 
 conv_pw_1_relu (ReLU)       (None, 16, 16, 64)        0         
                                                                 
 conv_pad_2 (ZeroPadding2D)  (None, 17, 17, 64)        0         
                                                                 
 conv_dw_2 (DepthwiseConv2D)  (None, 8, 8, 64)         576       
                                                                 
 conv_dw_2_bn (BatchNormaliz  (None, 8, 8, 64)         256       
 ation)                                                          
                                                                 
 conv_dw_2_relu (ReLU)       (None, 8, 8, 64)          0         
                                                                 
 conv_pw_2 (Conv2D)          (None, 8, 8, 128)         8192      
                                                                 
 conv_pw_2_bn (BatchNormaliz  (None, 8, 8, 128)        512       
 ation)                                                          
                                                                 
 conv_pw_2_relu (ReLU)       (None, 8, 8, 128)         0         
                                                                 
 conv_dw_3 (DepthwiseConv2D)  (None, 8, 8, 128)        1152      
                                                                 
 conv_dw_3_bn (BatchNormaliz  (None, 8, 8, 128)        512       
 ation)                                                          
                                                                 
 conv_dw_3_relu (ReLU)       (None, 8, 8, 128)         0         
                                                                 
 conv_pw_3 (Conv2D)          (None, 8, 8, 128)         16384     
                                                                 
 conv_pw_3_bn (BatchNormaliz  (None, 8, 8, 128)        512       
 ation)                                                          
                                                                 
 conv_pw_3_relu (ReLU)       (None, 8, 8, 128)         0         
                                                                 
 conv_pad_4 (ZeroPadding2D)  (None, 9, 9, 128)         0         
                                                                 
 conv_dw_4 (DepthwiseConv2D)  (None, 4, 4, 128)        1152      
                                                                 
 conv_dw_4_bn (BatchNormaliz  (None, 4, 4, 128)        512       
 ation)                                                          
                                                                 
 conv_dw_4_relu (ReLU)       (None, 4, 4, 128)         0         
                                                                 
 conv_pw_4 (Conv2D)          (None, 4, 4, 256)         32768     
                                                                 
 conv_pw_4_bn (BatchNormaliz  (None, 4, 4, 256)        1024      
 ation)                                                          
                                                                 
 conv_pw_4_relu (ReLU)       (None, 4, 4, 256)         0         
                                                                 
 conv_dw_5 (DepthwiseConv2D)  (None, 4, 4, 256)        2304      
                                                                 
 conv_dw_5_bn (BatchNormaliz  (None, 4, 4, 256)        1024      
 ation)                                                          
                                                                 
 conv_dw_5_relu (ReLU)       (None, 4, 4, 256)         0         
                                                                 
 conv_pw_5 (Conv2D)          (None, 4, 4, 256)         65536     
                                                                 
 conv_pw_5_bn (BatchNormaliz  (None, 4, 4, 256)        1024      
 ation)                                                          
                                                                 
 conv_pw_5_relu (ReLU)       (None, 4, 4, 256)         0         
                                                                 
 conv_pad_6 (ZeroPadding2D)  (None, 5, 5, 256)         0         
                                                                 
 conv_dw_6 (DepthwiseConv2D)  (None, 2, 2, 256)        2304      
                                                                 
 conv_dw_6_bn (BatchNormaliz  (None, 2, 2, 256)        1024      
 ation)                                                          
                                                                 
 conv_dw_6_relu (ReLU)       (None, 2, 2, 256)         0         
                                                                 
 conv_pw_6 (Conv2D)          (None, 2, 2, 512)         131072    
                                                                 
 conv_pw_6_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_pw_6_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_dw_7 (DepthwiseConv2D)  (None, 2, 2, 512)        4608      
                                                                 
 conv_dw_7_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_dw_7_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_pw_7 (Conv2D)          (None, 2, 2, 512)         262144    
                                                                 
 conv_pw_7_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_pw_7_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_dw_8 (DepthwiseConv2D)  (None, 2, 2, 512)        4608      
                                                                 
 conv_dw_8_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_dw_8_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_pw_8 (Conv2D)          (None, 2, 2, 512)         262144    
                                                                 
 conv_pw_8_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_pw_8_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_dw_9 (DepthwiseConv2D)  (None, 2, 2, 512)        4608      
                                                                 
 conv_dw_9_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_dw_9_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_pw_9 (Conv2D)          (None, 2, 2, 512)         262144    
                                                                 
 conv_pw_9_bn (BatchNormaliz  (None, 2, 2, 512)        2048      
 ation)                                                          
                                                                 
 conv_pw_9_relu (ReLU)       (None, 2, 2, 512)         0         
                                                                 
 conv_dw_10 (DepthwiseConv2D  (None, 2, 2, 512)        4608      
 )                                                               
                                                                 
 conv_dw_10_bn (BatchNormali  (None, 2, 2, 512)        2048      
 zation)                                                         
                                                                 
 conv_dw_10_relu (ReLU)      (None, 2, 2, 512)         0         
                                                                 
 conv_pw_10 (Conv2D)         (None, 2, 2, 512)         262144    
                                                                 
 conv_pw_10_bn (BatchNormali  (None, 2, 2, 512)        2048      
 zation)                                                         
                                                                 
 conv_pw_10_relu (ReLU)      (None, 2, 2, 512)         0         
                                                                 
 conv_dw_11 (DepthwiseConv2D  (None, 2, 2, 512)        4608      
 )                                                               
                                                                 
 conv_dw_11_bn (BatchNormali  (None, 2, 2, 512)        2048      
 zation)                                                         
                                                                 
 conv_dw_11_relu (ReLU)      (None, 2, 2, 512)         0         
                                                                 
 conv_pw_11 (Conv2D)         (None, 2, 2, 512)         262144    
                                                                 
 conv_pw_11_bn (BatchNormali  (None, 2, 2, 512)        2048      
 zation)                                                         
                                                                 
 conv_pw_11_relu (ReLU)      (None, 2, 2, 512)         0         
                                                                 
 conv_pad_12 (ZeroPadding2D)  (None, 3, 3, 512)        0         
                                                                 
 conv_dw_12 (DepthwiseConv2D  (None, 1, 1, 512)        4608      
 )                                                               
                                                                 
 conv_dw_12_bn (BatchNormali  (None, 1, 1, 512)        2048      
 zation)                                                         
                                                                 
 conv_dw_12_relu (ReLU)      (None, 1, 1, 512)         0         
                                                                 
 conv_pw_12 (Conv2D)         (None, 1, 1, 1024)        524288    
                                                                 
 conv_pw_12_bn (BatchNormali  (None, 1, 1, 1024)       4096      
 zation)                                                         
                                                                 
 conv_pw_12_relu (ReLU)      (None, 1, 1, 1024)        0         
                                                                 
 conv_dw_13 (DepthwiseConv2D  (None, 1, 1, 1024)       9216      
 )                                                               
                                                                 
 conv_dw_13_bn (BatchNormali  (None, 1, 1, 1024)       4096      
 zation)                                                         
                                                                 
 conv_dw_13_relu (ReLU)      (None, 1, 1, 1024)        0         
                                                                 
 conv_pw_13 (Conv2D)         (None, 1, 1, 1024)        1048576   
                                                                 
 conv_pw_13_bn (BatchNormali  (None, 1, 1, 1024)       4096      
 zation)                                                         
                                                                 
 conv_pw_13_relu (ReLU)      (None, 1, 1, 1024)        0         
                                                                 
 global_average_pooling2d_2   (None, 1024)             0         
 (GlobalAveragePooling2D)                                        
                                                                 
 dense_4 (Dense)             (None, 512)               524800    
                                                                 
 dropout_2 (Dropout)         (None, 512)               0         
                                                                 
 dense_5 (Dense)             (None, 1)                 513       
                                                                 
=================================================================
Total params: 3,754,177
Trainable params: 3,732,289
Non-trainable params: 21,888
_________________________________________________________________
Epoch 1/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.7742 - acc: 0.6444 - precision: 0.6448 - recall: 0.6432
Epoch 1: val_acc improved from -inf to 0.72278, saving model to /kaggle/working/weights.hdf5
1050/1050 [==============================] - 48s 31ms/step - loss: 0.7741 - acc: 0.6443 - precision: 0.6446 - recall: 0.6431 - val_loss: 0.5652 - val_acc: 0.7228 - val_precision: 0.7135 - val_recall: 0.7444 - lr: 0.0010
Epoch 2/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6185 - acc: 0.6939 - precision: 0.6881 - recall: 0.7092
Epoch 2: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 29ms/step - loss: 0.6183 - acc: 0.6939 - precision: 0.6881 - recall: 0.7093 - val_loss: 0.5771 - val_acc: 0.7156 - val_precision: 0.6732 - val_recall: 0.8378 - lr: 0.0010
Epoch 3/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.6064 - acc: 0.6865 - precision: 0.6643 - recall: 0.7546
Epoch 3: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 30ms/step - loss: 0.6062 - acc: 0.6865 - precision: 0.6642 - recall: 0.7548 - val_loss: 0.5969 - val_acc: 0.7100 - val_precision: 0.6687 - val_recall: 0.8322 - lr: 0.0010
Epoch 4/12
1049/1050 [============================>.] - ETA: 0s - loss: 0.6047 - acc: 0.6781 - precision: 0.6520 - recall: 0.7643
Epoch 4: val_acc did not improve from 0.72278
1050/1050 [==============================] - 31s 30ms/step - loss: 0.6047 - acc: 0.6781 - precision: 0.6519 - recall: 0.7643 - val_loss: 0.5965 - val_acc: 0.7100 - val_precision: 0.6828 - val_recall: 0.7844 - lr: 0.0010
Epoch 5/12
1050/1050 [==============================] - ETA: 0s - loss: 0.6108 - acc: 0.6854 - precision: 0.6649 - recall: 0.7474
Epoch 5: val_acc did not improve from 0.72278
1050/1050 [==============================] - 32s 31ms/step - loss: 0.6108 - acc: 0.6854 - precision: 0.6649 - recall: 0.7474 - val_loss: 0.6125 - val_acc: 0.6961 - val_precision: 0.6833 - val_recall: 0.7311 - lr: 0.0010
Epoch 6/12
1048/1050 [============================>.] - ETA: 0s - loss: 0.6238 - acc: 0.6534 - precision: 0.6305 - recall: 0.7429
Epoch 6: val_acc did not improve from 0.72278
1050/1050 [==============================] - 32s 30ms/step - loss: 0.6241 - acc: 0.6531 - precision: 0.6298 - recall: 0.7429 - val_loss: 0.6380 - val_acc: 0.5722 - val_precision: 0.5448 - val_recall: 0.8789 - lr: 0.0010
57/57 [==============================] - 1s 4ms/step



--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
                     precision    recall  f1-score   support

   Normal (Class 0)       0.76      0.66      0.71       900
Pneumonia (Class 1)       0.70      0.79      0.74       900

           accuracy                           0.73      1800
          macro avg       0.73      0.73      0.72      1800
       weighted avg       0.73      0.73      0.72      1800

--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>
In [ ]:
import tensorflow as tf
tf.config.optimizer.set_experimental_options({'layout_optimizer': False})
In [ ]:
model_7 = create_model_7()
history_7 = fit_model_tl(model_7)
evaluate_model_perf_tl(history_7, model_7, 'EfficientNetB0')
Model: "model_4"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 input_5 (InputLayer)           [(None, 32, 32, 3)]  0           []                               
                                                                                                  
 rescaling_2 (Rescaling)        (None, 32, 32, 3)    0           ['input_5[0][0]']                
                                                                                                  
 normalization_1 (Normalization  (None, 32, 32, 3)   7           ['rescaling_2[0][0]']            
 )                                                                                                
                                                                                                  
 rescaling_3 (Rescaling)        (None, 32, 32, 3)    0           ['normalization_1[0][0]']        
                                                                                                  
 stem_conv_pad (ZeroPadding2D)  (None, 33, 33, 3)    0           ['rescaling_3[0][0]']            
                                                                                                  
 stem_conv (Conv2D)             (None, 16, 16, 32)   864         ['stem_conv_pad[0][0]']          
                                                                                                  
 stem_bn (BatchNormalization)   (None, 16, 16, 32)   128         ['stem_conv[0][0]']              
                                                                                                  
 stem_activation (Activation)   (None, 16, 16, 32)   0           ['stem_bn[0][0]']                
                                                                                                  
 block1a_dwconv (DepthwiseConv2  (None, 16, 16, 32)  288         ['stem_activation[0][0]']        
 D)                                                                                               
                                                                                                  
 block1a_bn (BatchNormalization  (None, 16, 16, 32)  128         ['block1a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block1a_activation (Activation  (None, 16, 16, 32)  0           ['block1a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block1a_se_squeeze (GlobalAver  (None, 32)          0           ['block1a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block1a_se_reshape (Reshape)   (None, 1, 1, 32)     0           ['block1a_se_squeeze[0][0]']     
                                                                                                  
 block1a_se_reduce (Conv2D)     (None, 1, 1, 8)      264         ['block1a_se_reshape[0][0]']     
                                                                                                  
 block1a_se_expand (Conv2D)     (None, 1, 1, 32)     288         ['block1a_se_reduce[0][0]']      
                                                                                                  
 block1a_se_excite (Multiply)   (None, 16, 16, 32)   0           ['block1a_activation[0][0]',     
                                                                  'block1a_se_expand[0][0]']      
                                                                                                  
 block1a_project_conv (Conv2D)  (None, 16, 16, 16)   512         ['block1a_se_excite[0][0]']      
                                                                                                  
 block1a_project_bn (BatchNorma  (None, 16, 16, 16)  64          ['block1a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block2a_expand_conv (Conv2D)   (None, 16, 16, 96)   1536        ['block1a_project_bn[0][0]']     
                                                                                                  
 block2a_expand_bn (BatchNormal  (None, 16, 16, 96)  384         ['block2a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block2a_expand_activation (Act  (None, 16, 16, 96)  0           ['block2a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block2a_dwconv_pad (ZeroPaddin  (None, 17, 17, 96)  0           ['block2a_expand_activation[0][0]
 g2D)                                                            ']                               
                                                                                                  
 block2a_dwconv (DepthwiseConv2  (None, 8, 8, 96)    864         ['block2a_dwconv_pad[0][0]']     
 D)                                                                                               
                                                                                                  
 block2a_bn (BatchNormalization  (None, 8, 8, 96)    384         ['block2a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block2a_activation (Activation  (None, 8, 8, 96)    0           ['block2a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block2a_se_squeeze (GlobalAver  (None, 96)          0           ['block2a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block2a_se_reshape (Reshape)   (None, 1, 1, 96)     0           ['block2a_se_squeeze[0][0]']     
                                                                                                  
 block2a_se_reduce (Conv2D)     (None, 1, 1, 4)      388         ['block2a_se_reshape[0][0]']     
                                                                                                  
 block2a_se_expand (Conv2D)     (None, 1, 1, 96)     480         ['block2a_se_reduce[0][0]']      
                                                                                                  
 block2a_se_excite (Multiply)   (None, 8, 8, 96)     0           ['block2a_activation[0][0]',     
                                                                  'block2a_se_expand[0][0]']      
                                                                                                  
 block2a_project_conv (Conv2D)  (None, 8, 8, 24)     2304        ['block2a_se_excite[0][0]']      
                                                                                                  
 block2a_project_bn (BatchNorma  (None, 8, 8, 24)    96          ['block2a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block2b_expand_conv (Conv2D)   (None, 8, 8, 144)    3456        ['block2a_project_bn[0][0]']     
                                                                                                  
 block2b_expand_bn (BatchNormal  (None, 8, 8, 144)   576         ['block2b_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block2b_expand_activation (Act  (None, 8, 8, 144)   0           ['block2b_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block2b_dwconv (DepthwiseConv2  (None, 8, 8, 144)   1296        ['block2b_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block2b_bn (BatchNormalization  (None, 8, 8, 144)   576         ['block2b_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block2b_activation (Activation  (None, 8, 8, 144)   0           ['block2b_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block2b_se_squeeze (GlobalAver  (None, 144)         0           ['block2b_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block2b_se_reshape (Reshape)   (None, 1, 1, 144)    0           ['block2b_se_squeeze[0][0]']     
                                                                                                  
 block2b_se_reduce (Conv2D)     (None, 1, 1, 6)      870         ['block2b_se_reshape[0][0]']     
                                                                                                  
 block2b_se_expand (Conv2D)     (None, 1, 1, 144)    1008        ['block2b_se_reduce[0][0]']      
                                                                                                  
 block2b_se_excite (Multiply)   (None, 8, 8, 144)    0           ['block2b_activation[0][0]',     
                                                                  'block2b_se_expand[0][0]']      
                                                                                                  
 block2b_project_conv (Conv2D)  (None, 8, 8, 24)     3456        ['block2b_se_excite[0][0]']      
                                                                                                  
 block2b_project_bn (BatchNorma  (None, 8, 8, 24)    96          ['block2b_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block2b_drop (Dropout)         (None, 8, 8, 24)     0           ['block2b_project_bn[0][0]']     
                                                                                                  
 block2b_add (Add)              (None, 8, 8, 24)     0           ['block2b_drop[0][0]',           
                                                                  'block2a_project_bn[0][0]']     
                                                                                                  
 block3a_expand_conv (Conv2D)   (None, 8, 8, 144)    3456        ['block2b_add[0][0]']            
                                                                                                  
 block3a_expand_bn (BatchNormal  (None, 8, 8, 144)   576         ['block3a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block3a_expand_activation (Act  (None, 8, 8, 144)   0           ['block3a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block3a_dwconv_pad (ZeroPaddin  (None, 11, 11, 144)  0          ['block3a_expand_activation[0][0]
 g2D)                                                            ']                               
                                                                                                  
 block3a_dwconv (DepthwiseConv2  (None, 4, 4, 144)   3600        ['block3a_dwconv_pad[0][0]']     
 D)                                                                                               
                                                                                                  
 block3a_bn (BatchNormalization  (None, 4, 4, 144)   576         ['block3a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block3a_activation (Activation  (None, 4, 4, 144)   0           ['block3a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block3a_se_squeeze (GlobalAver  (None, 144)         0           ['block3a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block3a_se_reshape (Reshape)   (None, 1, 1, 144)    0           ['block3a_se_squeeze[0][0]']     
                                                                                                  
 block3a_se_reduce (Conv2D)     (None, 1, 1, 6)      870         ['block3a_se_reshape[0][0]']     
                                                                                                  
 block3a_se_expand (Conv2D)     (None, 1, 1, 144)    1008        ['block3a_se_reduce[0][0]']      
                                                                                                  
 block3a_se_excite (Multiply)   (None, 4, 4, 144)    0           ['block3a_activation[0][0]',     
                                                                  'block3a_se_expand[0][0]']      
                                                                                                  
 block3a_project_conv (Conv2D)  (None, 4, 4, 40)     5760        ['block3a_se_excite[0][0]']      
                                                                                                  
 block3a_project_bn (BatchNorma  (None, 4, 4, 40)    160         ['block3a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block3b_expand_conv (Conv2D)   (None, 4, 4, 240)    9600        ['block3a_project_bn[0][0]']     
                                                                                                  
 block3b_expand_bn (BatchNormal  (None, 4, 4, 240)   960         ['block3b_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block3b_expand_activation (Act  (None, 4, 4, 240)   0           ['block3b_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block3b_dwconv (DepthwiseConv2  (None, 4, 4, 240)   6000        ['block3b_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block3b_bn (BatchNormalization  (None, 4, 4, 240)   960         ['block3b_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block3b_activation (Activation  (None, 4, 4, 240)   0           ['block3b_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block3b_se_squeeze (GlobalAver  (None, 240)         0           ['block3b_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block3b_se_reshape (Reshape)   (None, 1, 1, 240)    0           ['block3b_se_squeeze[0][0]']     
                                                                                                  
 block3b_se_reduce (Conv2D)     (None, 1, 1, 10)     2410        ['block3b_se_reshape[0][0]']     
                                                                                                  
 block3b_se_expand (Conv2D)     (None, 1, 1, 240)    2640        ['block3b_se_reduce[0][0]']      
                                                                                                  
 block3b_se_excite (Multiply)   (None, 4, 4, 240)    0           ['block3b_activation[0][0]',     
                                                                  'block3b_se_expand[0][0]']      
                                                                                                  
 block3b_project_conv (Conv2D)  (None, 4, 4, 40)     9600        ['block3b_se_excite[0][0]']      
                                                                                                  
 block3b_project_bn (BatchNorma  (None, 4, 4, 40)    160         ['block3b_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block3b_drop (Dropout)         (None, 4, 4, 40)     0           ['block3b_project_bn[0][0]']     
                                                                                                  
 block3b_add (Add)              (None, 4, 4, 40)     0           ['block3b_drop[0][0]',           
                                                                  'block3a_project_bn[0][0]']     
                                                                                                  
 block4a_expand_conv (Conv2D)   (None, 4, 4, 240)    9600        ['block3b_add[0][0]']            
                                                                                                  
 block4a_expand_bn (BatchNormal  (None, 4, 4, 240)   960         ['block4a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block4a_expand_activation (Act  (None, 4, 4, 240)   0           ['block4a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block4a_dwconv_pad (ZeroPaddin  (None, 5, 5, 240)   0           ['block4a_expand_activation[0][0]
 g2D)                                                            ']                               
                                                                                                  
 block4a_dwconv (DepthwiseConv2  (None, 2, 2, 240)   2160        ['block4a_dwconv_pad[0][0]']     
 D)                                                                                               
                                                                                                  
 block4a_bn (BatchNormalization  (None, 2, 2, 240)   960         ['block4a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block4a_activation (Activation  (None, 2, 2, 240)   0           ['block4a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block4a_se_squeeze (GlobalAver  (None, 240)         0           ['block4a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block4a_se_reshape (Reshape)   (None, 1, 1, 240)    0           ['block4a_se_squeeze[0][0]']     
                                                                                                  
 block4a_se_reduce (Conv2D)     (None, 1, 1, 10)     2410        ['block4a_se_reshape[0][0]']     
                                                                                                  
 block4a_se_expand (Conv2D)     (None, 1, 1, 240)    2640        ['block4a_se_reduce[0][0]']      
                                                                                                  
 block4a_se_excite (Multiply)   (None, 2, 2, 240)    0           ['block4a_activation[0][0]',     
                                                                  'block4a_se_expand[0][0]']      
                                                                                                  
 block4a_project_conv (Conv2D)  (None, 2, 2, 80)     19200       ['block4a_se_excite[0][0]']      
                                                                                                  
 block4a_project_bn (BatchNorma  (None, 2, 2, 80)    320         ['block4a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block4b_expand_conv (Conv2D)   (None, 2, 2, 480)    38400       ['block4a_project_bn[0][0]']     
                                                                                                  
 block4b_expand_bn (BatchNormal  (None, 2, 2, 480)   1920        ['block4b_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block4b_expand_activation (Act  (None, 2, 2, 480)   0           ['block4b_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block4b_dwconv (DepthwiseConv2  (None, 2, 2, 480)   4320        ['block4b_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block4b_bn (BatchNormalization  (None, 2, 2, 480)   1920        ['block4b_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block4b_activation (Activation  (None, 2, 2, 480)   0           ['block4b_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block4b_se_squeeze (GlobalAver  (None, 480)         0           ['block4b_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block4b_se_reshape (Reshape)   (None, 1, 1, 480)    0           ['block4b_se_squeeze[0][0]']     
                                                                                                  
 block4b_se_reduce (Conv2D)     (None, 1, 1, 20)     9620        ['block4b_se_reshape[0][0]']     
                                                                                                  
 block4b_se_expand (Conv2D)     (None, 1, 1, 480)    10080       ['block4b_se_reduce[0][0]']      
                                                                                                  
 block4b_se_excite (Multiply)   (None, 2, 2, 480)    0           ['block4b_activation[0][0]',     
                                                                  'block4b_se_expand[0][0]']      
                                                                                                  
 block4b_project_conv (Conv2D)  (None, 2, 2, 80)     38400       ['block4b_se_excite[0][0]']      
                                                                                                  
 block4b_project_bn (BatchNorma  (None, 2, 2, 80)    320         ['block4b_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block4b_drop (Dropout)         (None, 2, 2, 80)     0           ['block4b_project_bn[0][0]']     
                                                                                                  
 block4b_add (Add)              (None, 2, 2, 80)     0           ['block4b_drop[0][0]',           
                                                                  'block4a_project_bn[0][0]']     
                                                                                                  
 block4c_expand_conv (Conv2D)   (None, 2, 2, 480)    38400       ['block4b_add[0][0]']            
                                                                                                  
 block4c_expand_bn (BatchNormal  (None, 2, 2, 480)   1920        ['block4c_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block4c_expand_activation (Act  (None, 2, 2, 480)   0           ['block4c_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block4c_dwconv (DepthwiseConv2  (None, 2, 2, 480)   4320        ['block4c_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block4c_bn (BatchNormalization  (None, 2, 2, 480)   1920        ['block4c_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block4c_activation (Activation  (None, 2, 2, 480)   0           ['block4c_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block4c_se_squeeze (GlobalAver  (None, 480)         0           ['block4c_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block4c_se_reshape (Reshape)   (None, 1, 1, 480)    0           ['block4c_se_squeeze[0][0]']     
                                                                                                  
 block4c_se_reduce (Conv2D)     (None, 1, 1, 20)     9620        ['block4c_se_reshape[0][0]']     
                                                                                                  
 block4c_se_expand (Conv2D)     (None, 1, 1, 480)    10080       ['block4c_se_reduce[0][0]']      
                                                                                                  
 block4c_se_excite (Multiply)   (None, 2, 2, 480)    0           ['block4c_activation[0][0]',     
                                                                  'block4c_se_expand[0][0]']      
                                                                                                  
 block4c_project_conv (Conv2D)  (None, 2, 2, 80)     38400       ['block4c_se_excite[0][0]']      
                                                                                                  
 block4c_project_bn (BatchNorma  (None, 2, 2, 80)    320         ['block4c_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block4c_drop (Dropout)         (None, 2, 2, 80)     0           ['block4c_project_bn[0][0]']     
                                                                                                  
 block4c_add (Add)              (None, 2, 2, 80)     0           ['block4c_drop[0][0]',           
                                                                  'block4b_add[0][0]']            
                                                                                                  
 block5a_expand_conv (Conv2D)   (None, 2, 2, 480)    38400       ['block4c_add[0][0]']            
                                                                                                  
 block5a_expand_bn (BatchNormal  (None, 2, 2, 480)   1920        ['block5a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block5a_expand_activation (Act  (None, 2, 2, 480)   0           ['block5a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block5a_dwconv (DepthwiseConv2  (None, 2, 2, 480)   12000       ['block5a_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block5a_bn (BatchNormalization  (None, 2, 2, 480)   1920        ['block5a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block5a_activation (Activation  (None, 2, 2, 480)   0           ['block5a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block5a_se_squeeze (GlobalAver  (None, 480)         0           ['block5a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block5a_se_reshape (Reshape)   (None, 1, 1, 480)    0           ['block5a_se_squeeze[0][0]']     
                                                                                                  
 block5a_se_reduce (Conv2D)     (None, 1, 1, 20)     9620        ['block5a_se_reshape[0][0]']     
                                                                                                  
 block5a_se_expand (Conv2D)     (None, 1, 1, 480)    10080       ['block5a_se_reduce[0][0]']      
                                                                                                  
 block5a_se_excite (Multiply)   (None, 2, 2, 480)    0           ['block5a_activation[0][0]',     
                                                                  'block5a_se_expand[0][0]']      
                                                                                                  
 block5a_project_conv (Conv2D)  (None, 2, 2, 112)    53760       ['block5a_se_excite[0][0]']      
                                                                                                  
 block5a_project_bn (BatchNorma  (None, 2, 2, 112)   448         ['block5a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block5b_expand_conv (Conv2D)   (None, 2, 2, 672)    75264       ['block5a_project_bn[0][0]']     
                                                                                                  
 block5b_expand_bn (BatchNormal  (None, 2, 2, 672)   2688        ['block5b_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block5b_expand_activation (Act  (None, 2, 2, 672)   0           ['block5b_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block5b_dwconv (DepthwiseConv2  (None, 2, 2, 672)   16800       ['block5b_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block5b_bn (BatchNormalization  (None, 2, 2, 672)   2688        ['block5b_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block5b_activation (Activation  (None, 2, 2, 672)   0           ['block5b_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block5b_se_squeeze (GlobalAver  (None, 672)         0           ['block5b_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block5b_se_reshape (Reshape)   (None, 1, 1, 672)    0           ['block5b_se_squeeze[0][0]']     
                                                                                                  
 block5b_se_reduce (Conv2D)     (None, 1, 1, 28)     18844       ['block5b_se_reshape[0][0]']     
                                                                                                  
 block5b_se_expand (Conv2D)     (None, 1, 1, 672)    19488       ['block5b_se_reduce[0][0]']      
                                                                                                  
 block5b_se_excite (Multiply)   (None, 2, 2, 672)    0           ['block5b_activation[0][0]',     
                                                                  'block5b_se_expand[0][0]']      
                                                                                                  
 block5b_project_conv (Conv2D)  (None, 2, 2, 112)    75264       ['block5b_se_excite[0][0]']      
                                                                                                  
 block5b_project_bn (BatchNorma  (None, 2, 2, 112)   448         ['block5b_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block5b_drop (Dropout)         (None, 2, 2, 112)    0           ['block5b_project_bn[0][0]']     
                                                                                                  
 block5b_add (Add)              (None, 2, 2, 112)    0           ['block5b_drop[0][0]',           
                                                                  'block5a_project_bn[0][0]']     
                                                                                                  
 block5c_expand_conv (Conv2D)   (None, 2, 2, 672)    75264       ['block5b_add[0][0]']            
                                                                                                  
 block5c_expand_bn (BatchNormal  (None, 2, 2, 672)   2688        ['block5c_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block5c_expand_activation (Act  (None, 2, 2, 672)   0           ['block5c_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block5c_dwconv (DepthwiseConv2  (None, 2, 2, 672)   16800       ['block5c_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block5c_bn (BatchNormalization  (None, 2, 2, 672)   2688        ['block5c_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block5c_activation (Activation  (None, 2, 2, 672)   0           ['block5c_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block5c_se_squeeze (GlobalAver  (None, 672)         0           ['block5c_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block5c_se_reshape (Reshape)   (None, 1, 1, 672)    0           ['block5c_se_squeeze[0][0]']     
                                                                                                  
 block5c_se_reduce (Conv2D)     (None, 1, 1, 28)     18844       ['block5c_se_reshape[0][0]']     
                                                                                                  
 block5c_se_expand (Conv2D)     (None, 1, 1, 672)    19488       ['block5c_se_reduce[0][0]']      
                                                                                                  
 block5c_se_excite (Multiply)   (None, 2, 2, 672)    0           ['block5c_activation[0][0]',     
                                                                  'block5c_se_expand[0][0]']      
                                                                                                  
 block5c_project_conv (Conv2D)  (None, 2, 2, 112)    75264       ['block5c_se_excite[0][0]']      
                                                                                                  
 block5c_project_bn (BatchNorma  (None, 2, 2, 112)   448         ['block5c_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block5c_drop (Dropout)         (None, 2, 2, 112)    0           ['block5c_project_bn[0][0]']     
                                                                                                  
 block5c_add (Add)              (None, 2, 2, 112)    0           ['block5c_drop[0][0]',           
                                                                  'block5b_add[0][0]']            
                                                                                                  
 block6a_expand_conv (Conv2D)   (None, 2, 2, 672)    75264       ['block5c_add[0][0]']            
                                                                                                  
 block6a_expand_bn (BatchNormal  (None, 2, 2, 672)   2688        ['block6a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block6a_expand_activation (Act  (None, 2, 2, 672)   0           ['block6a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block6a_dwconv_pad (ZeroPaddin  (None, 5, 5, 672)   0           ['block6a_expand_activation[0][0]
 g2D)                                                            ']                               
                                                                                                  
 block6a_dwconv (DepthwiseConv2  (None, 1, 1, 672)   16800       ['block6a_dwconv_pad[0][0]']     
 D)                                                                                               
                                                                                                  
 block6a_bn (BatchNormalization  (None, 1, 1, 672)   2688        ['block6a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block6a_activation (Activation  (None, 1, 1, 672)   0           ['block6a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block6a_se_squeeze (GlobalAver  (None, 672)         0           ['block6a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block6a_se_reshape (Reshape)   (None, 1, 1, 672)    0           ['block6a_se_squeeze[0][0]']     
                                                                                                  
 block6a_se_reduce (Conv2D)     (None, 1, 1, 28)     18844       ['block6a_se_reshape[0][0]']     
                                                                                                  
 block6a_se_expand (Conv2D)     (None, 1, 1, 672)    19488       ['block6a_se_reduce[0][0]']      
                                                                                                  
 block6a_se_excite (Multiply)   (None, 1, 1, 672)    0           ['block6a_activation[0][0]',     
                                                                  'block6a_se_expand[0][0]']      
                                                                                                  
 block6a_project_conv (Conv2D)  (None, 1, 1, 192)    129024      ['block6a_se_excite[0][0]']      
                                                                                                  
 block6a_project_bn (BatchNorma  (None, 1, 1, 192)   768         ['block6a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block6b_expand_conv (Conv2D)   (None, 1, 1, 1152)   221184      ['block6a_project_bn[0][0]']     
                                                                                                  
 block6b_expand_bn (BatchNormal  (None, 1, 1, 1152)  4608        ['block6b_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block6b_expand_activation (Act  (None, 1, 1, 1152)  0           ['block6b_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block6b_dwconv (DepthwiseConv2  (None, 1, 1, 1152)  28800       ['block6b_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block6b_bn (BatchNormalization  (None, 1, 1, 1152)  4608        ['block6b_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block6b_activation (Activation  (None, 1, 1, 1152)  0           ['block6b_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block6b_se_squeeze (GlobalAver  (None, 1152)        0           ['block6b_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block6b_se_reshape (Reshape)   (None, 1, 1, 1152)   0           ['block6b_se_squeeze[0][0]']     
                                                                                                  
 block6b_se_reduce (Conv2D)     (None, 1, 1, 48)     55344       ['block6b_se_reshape[0][0]']     
                                                                                                  
 block6b_se_expand (Conv2D)     (None, 1, 1, 1152)   56448       ['block6b_se_reduce[0][0]']      
                                                                                                  
 block6b_se_excite (Multiply)   (None, 1, 1, 1152)   0           ['block6b_activation[0][0]',     
                                                                  'block6b_se_expand[0][0]']      
                                                                                                  
 block6b_project_conv (Conv2D)  (None, 1, 1, 192)    221184      ['block6b_se_excite[0][0]']      
                                                                                                  
 block6b_project_bn (BatchNorma  (None, 1, 1, 192)   768         ['block6b_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block6b_drop (Dropout)         (None, 1, 1, 192)    0           ['block6b_project_bn[0][0]']     
                                                                                                  
 block6b_add (Add)              (None, 1, 1, 192)    0           ['block6b_drop[0][0]',           
                                                                  'block6a_project_bn[0][0]']     
                                                                                                  
 block6c_expand_conv (Conv2D)   (None, 1, 1, 1152)   221184      ['block6b_add[0][0]']            
                                                                                                  
 block6c_expand_bn (BatchNormal  (None, 1, 1, 1152)  4608        ['block6c_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block6c_expand_activation (Act  (None, 1, 1, 1152)  0           ['block6c_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block6c_dwconv (DepthwiseConv2  (None, 1, 1, 1152)  28800       ['block6c_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block6c_bn (BatchNormalization  (None, 1, 1, 1152)  4608        ['block6c_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block6c_activation (Activation  (None, 1, 1, 1152)  0           ['block6c_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block6c_se_squeeze (GlobalAver  (None, 1152)        0           ['block6c_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block6c_se_reshape (Reshape)   (None, 1, 1, 1152)   0           ['block6c_se_squeeze[0][0]']     
                                                                                                  
 block6c_se_reduce (Conv2D)     (None, 1, 1, 48)     55344       ['block6c_se_reshape[0][0]']     
                                                                                                  
 block6c_se_expand (Conv2D)     (None, 1, 1, 1152)   56448       ['block6c_se_reduce[0][0]']      
                                                                                                  
 block6c_se_excite (Multiply)   (None, 1, 1, 1152)   0           ['block6c_activation[0][0]',     
                                                                  'block6c_se_expand[0][0]']      
                                                                                                  
 block6c_project_conv (Conv2D)  (None, 1, 1, 192)    221184      ['block6c_se_excite[0][0]']      
                                                                                                  
 block6c_project_bn (BatchNorma  (None, 1, 1, 192)   768         ['block6c_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block6c_drop (Dropout)         (None, 1, 1, 192)    0           ['block6c_project_bn[0][0]']     
                                                                                                  
 block6c_add (Add)              (None, 1, 1, 192)    0           ['block6c_drop[0][0]',           
                                                                  'block6b_add[0][0]']            
                                                                                                  
 block6d_expand_conv (Conv2D)   (None, 1, 1, 1152)   221184      ['block6c_add[0][0]']            
                                                                                                  
 block6d_expand_bn (BatchNormal  (None, 1, 1, 1152)  4608        ['block6d_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block6d_expand_activation (Act  (None, 1, 1, 1152)  0           ['block6d_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block6d_dwconv (DepthwiseConv2  (None, 1, 1, 1152)  28800       ['block6d_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block6d_bn (BatchNormalization  (None, 1, 1, 1152)  4608        ['block6d_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block6d_activation (Activation  (None, 1, 1, 1152)  0           ['block6d_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block6d_se_squeeze (GlobalAver  (None, 1152)        0           ['block6d_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block6d_se_reshape (Reshape)   (None, 1, 1, 1152)   0           ['block6d_se_squeeze[0][0]']     
                                                                                                  
 block6d_se_reduce (Conv2D)     (None, 1, 1, 48)     55344       ['block6d_se_reshape[0][0]']     
                                                                                                  
 block6d_se_expand (Conv2D)     (None, 1, 1, 1152)   56448       ['block6d_se_reduce[0][0]']      
                                                                                                  
 block6d_se_excite (Multiply)   (None, 1, 1, 1152)   0           ['block6d_activation[0][0]',     
                                                                  'block6d_se_expand[0][0]']      
                                                                                                  
 block6d_project_conv (Conv2D)  (None, 1, 1, 192)    221184      ['block6d_se_excite[0][0]']      
                                                                                                  
 block6d_project_bn (BatchNorma  (None, 1, 1, 192)   768         ['block6d_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 block6d_drop (Dropout)         (None, 1, 1, 192)    0           ['block6d_project_bn[0][0]']     
                                                                                                  
 block6d_add (Add)              (None, 1, 1, 192)    0           ['block6d_drop[0][0]',           
                                                                  'block6c_add[0][0]']            
                                                                                                  
 block7a_expand_conv (Conv2D)   (None, 1, 1, 1152)   221184      ['block6d_add[0][0]']            
                                                                                                  
 block7a_expand_bn (BatchNormal  (None, 1, 1, 1152)  4608        ['block7a_expand_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 block7a_expand_activation (Act  (None, 1, 1, 1152)  0           ['block7a_expand_bn[0][0]']      
 ivation)                                                                                         
                                                                                                  
 block7a_dwconv (DepthwiseConv2  (None, 1, 1, 1152)  10368       ['block7a_expand_activation[0][0]
 D)                                                              ']                               
                                                                                                  
 block7a_bn (BatchNormalization  (None, 1, 1, 1152)  4608        ['block7a_dwconv[0][0]']         
 )                                                                                                
                                                                                                  
 block7a_activation (Activation  (None, 1, 1, 1152)  0           ['block7a_bn[0][0]']             
 )                                                                                                
                                                                                                  
 block7a_se_squeeze (GlobalAver  (None, 1152)        0           ['block7a_activation[0][0]']     
 agePooling2D)                                                                                    
                                                                                                  
 block7a_se_reshape (Reshape)   (None, 1, 1, 1152)   0           ['block7a_se_squeeze[0][0]']     
                                                                                                  
 block7a_se_reduce (Conv2D)     (None, 1, 1, 48)     55344       ['block7a_se_reshape[0][0]']     
                                                                                                  
 block7a_se_expand (Conv2D)     (None, 1, 1, 1152)   56448       ['block7a_se_reduce[0][0]']      
                                                                                                  
 block7a_se_excite (Multiply)   (None, 1, 1, 1152)   0           ['block7a_activation[0][0]',     
                                                                  'block7a_se_expand[0][0]']      
                                                                                                  
 block7a_project_conv (Conv2D)  (None, 1, 1, 320)    368640      ['block7a_se_excite[0][0]']      
                                                                                                  
 block7a_project_bn (BatchNorma  (None, 1, 1, 320)   1280        ['block7a_project_conv[0][0]']   
 lization)                                                                                        
                                                                                                  
 top_conv (Conv2D)              (None, 1, 1, 1280)   409600      ['block7a_project_bn[0][0]']     
                                                                                                  
 top_bn (BatchNormalization)    (None, 1, 1, 1280)   5120        ['top_conv[0][0]']               
                                                                                                  
 top_activation (Activation)    (None, 1, 1, 1280)   0           ['top_bn[0][0]']                 
                                                                                                  
 global_average_pooling2d_4 (Gl  (None, 1280)        0           ['top_activation[0][0]']         
 obalAveragePooling2D)                                                                            
                                                                                                  
 dense_8 (Dense)                (None, 512)          655872      ['global_average_pooling2d_4[0][0
                                                                 ]']                              
                                                                                                  
 dropout_4 (Dropout)            (None, 512)          0           ['dense_8[0][0]']                
                                                                                                  
 dense_9 (Dense)                (None, 1)            513         ['dropout_4[0][0]']              
                                                                                                  
==================================================================================================
Total params: 4,705,956
Trainable params: 4,663,933
Non-trainable params: 42,023
__________________________________________________________________________________________________
Epoch 1/12
1050/1050 [==============================] - 110s 63ms/step - loss: 0.7208 - accuracy: 0.6196 - val_loss: 1.4250 - val_accuracy: 0.4744 - lr: 0.0010
Epoch 2/12
1050/1050 [==============================] - 66s 62ms/step - loss: 0.6251 - accuracy: 0.6718 - val_loss: 0.9072 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 3/12
1050/1050 [==============================] - 66s 63ms/step - loss: 0.6310 - accuracy: 0.6650 - val_loss: 0.7158 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 4/12
1050/1050 [==============================] - ETA: 0s - loss: 0.6358 - accuracy: 0.6638
Epoch 4: ReduceLROnPlateau reducing learning rate to 0.0003000000142492354.
1050/1050 [==============================] - 67s 64ms/step - loss: 0.6358 - accuracy: 0.6638 - val_loss: 0.7876 - val_accuracy: 0.5000 - lr: 0.0010
Epoch 5/12
1050/1050 [==============================] - 67s 63ms/step - loss: 0.6035 - accuracy: 0.6924 - val_loss: 0.6128 - val_accuracy: 0.6739 - lr: 3.0000e-04
Epoch 6/12
1050/1050 [==============================] - 67s 64ms/step - loss: 0.5947 - accuracy: 0.6955 - val_loss: 0.7092 - val_accuracy: 0.5000 - lr: 3.0000e-04
Epoch 7/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5948 - accuracy: 0.6943
Epoch 7: ReduceLROnPlateau reducing learning rate to 9.000000427477062e-05.
1050/1050 [==============================] - 67s 64ms/step - loss: 0.5948 - accuracy: 0.6943 - val_loss: 0.6702 - val_accuracy: 0.6428 - lr: 3.0000e-04
Epoch 8/12
1050/1050 [==============================] - 67s 63ms/step - loss: 0.5931 - accuracy: 0.7001 - val_loss: 0.5902 - val_accuracy: 0.6939 - lr: 9.0000e-05
Epoch 9/12
1050/1050 [==============================] - 68s 64ms/step - loss: 0.5768 - accuracy: 0.7101 - val_loss: 0.5708 - val_accuracy: 0.6989 - lr: 9.0000e-05
Epoch 10/12
1050/1050 [==============================] - 74s 70ms/step - loss: 0.5684 - accuracy: 0.7179 - val_loss: 0.6469 - val_accuracy: 0.5650 - lr: 9.0000e-05
Epoch 11/12
1050/1050 [==============================] - ETA: 0s - loss: 0.5688 - accuracy: 0.7156
Epoch 11: ReduceLROnPlateau reducing learning rate to 2.700000040931627e-05.
1050/1050 [==============================] - 71s 67ms/step - loss: 0.5688 - accuracy: 0.7156 - val_loss: 1.0351 - val_accuracy: 0.5000 - lr: 9.0000e-05
Epoch 12/12
1050/1050 [==============================] - 68s 65ms/step - loss: 0.5579 - accuracy: 0.7289 - val_loss: 0.5634 - val_accuracy: 0.7256 - lr: 2.7000e-05
57/57 [==============================] - 2s 8ms/step



--------------------------------------------------------------------------------
Classification Matrix
--------------------------------------------------------------------------------
                     precision    recall  f1-score   support

   Normal (Class 0)       0.75      0.63      0.68       900
Pneumonia (Class 1)       0.68      0.79      0.73       900

           accuracy                           0.71      1800
          macro avg       0.71      0.71      0.71      1800
       weighted avg       0.71      0.71      0.71      1800

--------------------------------------------------------------------------------
<Figure size 640x480 with 0 Axes>

Observation:

In the series of experiments conducted to optimize pneumonia detection from chest X-ray images, several critical components were examined. The preprocessing stage standardized the image sizes and augmented the dataset, while five distinct pre-trained deep learning models, including ResNet50, ResNet101, MobileNet, EfficientNetB0, and VGG19, were rigorously tested. These models, loaded with pre-trained weights from ImageNet, were fine-tuned to enhance their performance.

The training strategy employed categorical cross-entropy loss and the Adam optimizer, supplemented with early stopping and learning rate reduction on a plateau to counter overfitting. Subsequently, an in-depth evaluation of these models revealed key performance metrics, including accuracy, AUC, precision, recall, and F1-score, shedding light on their effectiveness.

Among the various models assessed, MobileNet emerged as the frontrunner in the pursuit of accurate pneumonia detection. With an impressive accuracy rate of 73% and an AUC score of 77.56, MobileNet outperformed its counterparts. Its noteworthy attribute was the equilibrium it struck between precision and recall for both normal and pneumonia cases, rendering it particularly suitable for real-world deployment.

EfficientNetB0 also displayed competitive performance with accuracy rate of 71% and an AUC score of 74.11, closely following MobileNet with commendable precision and recall metrics. These models excelled in the crucial task of distinguishing between normal and pneumonia cases, signifying their potential as valuable tools in medical diagnosis. Ultimately, while the other models offered valuable insights, MobileNet's robust and balanced performance made it the standout choice for pneumonia detection from chest X-ray images.

Limitations of Transfer Learning

While transfer learning offers many advantages in training deep neural networks for image classification tasks, it also comes with certain limitations and considerations that should be acknowledged:

  • Domain Mismatch

Transfer learning assumes that the source domain (pre-trained model's domain) and the target domain (Healthcare Domain) have some degree of similarity. If the domains are significantly different, the pre-trained model's features may not be relevant, leading to suboptimal performance. For example, if the source domain is natural images, and the target domain is medical images, domain mismatch issues may arise.

  • Fine-Tuning Challenges Fine-tuning a pre-trained model requires selecting appropriate layers to train, freezing others, and choosing suitable learning rates. If not done correctly, it can lead to overfitting or underfitting. Fine-tuning can be a time-consuming and resource-intensive process, requiring careful experimentation.

  • Lack of Explainability Transfer learning models, especially deep neural networks with numerous layers, can be challenging to interpret and explain. This lack of transparency can be a limitation, particularly in medical applications where understanding the model's decisions is crucial.

  • Data Quantity and Quality The success of transfer learning often depends on having a sufficient amount of high-quality data. In some cases, medical datasets may be limited, leading to potential issues with model generalization. Augmenting the dataset and ensuring data quality are essential steps to mitigate this limitation.

  • Task-Specific Features Pre-trained models are designed for general-purpose tasks such as object recognition or image classification. They may not capture task-specific features or nuances in the target domain. Fine-tuning can help adapt the model, but there may still be limitations in capturing domain-specific knowledge.

  • Ethical Considerations When using pre-trained models for medical diagnosis or other critical applications, ethical considerations come into play. The model's performance, biases, and potential consequences of false positives or false negatives must be carefully evaluated and monitored.

  • Computational Resources Training and fine-tuning deep learning models, especially large ones like those in the report, require significant computational resources. Deploying such models in resource-constrained environments may not always be feasible.

  • Model Updates Pre-trained models may become outdated as new architectures and techniques emerge. Regularly updating and retraining models to incorporate the latest advancements is essential to maintain high performance.

Understanding these limitations and carefully considering them during the model development process is crucial for making informed decisions when applying transfer learning to specific tasks, particularly in critical domains like healthcare. It's essential to strike a balance between leveraging pre-trained knowledge and tailoring models to suit the unique requirements of the target domain.

Step 3: Design, train and test RCNN & its hybrids based object detection models to impose the bounding box or mask over the area of interest.¶

1. Basic RCNN Model with Selective Search¶

What is RCNN?

Region-based Convolutional Neural Network was developed by Ross Girshick. It is an Object Detection Algorithm which is region based. This family of machine learning models is mostly used in computer vision, especially for object detection where multiple objects are involved.

Difference between CNN and RCNN

Convolutional Neural Network (CNN) is primarily used for image classification, whereas RCNN is used for object detection. CNN can only give us information regarding the class of the objects, and the location of the object being classified is not identified. CNN also does not perform well when there are multiple different objects in the visual field due to interference.

On the other hand, when it comes to RCNN, object localization is the primary problem that needs to be solved for object detection. Object detection helps identify types or classes of objects whose presence is located. The brute force approach also called exhaustive search uses a sliding window of different sizes to locate the objects in the image.

R-CNN uses a combination of both segmentation and exhaustive search which is called selective search. The input image is segmented into different regions and the different shapes are separated by using different colors.

An iterative greedy algorithm approach repeatedly combines smaller regions with larger regions. The selective search proposes candidate object locations from region proposals. Features for these proposals were computed by feeding them into CNN architecture. A class-specific linear SVM model is used to classify each region.

Architecture of RCNN

The images given as input are run through the search algorithm to extract region proposals. The regions that are warped are fed into CNN architecture and finally, the regions are classified using support vectors.

Each class is independently trained by a binary SVM model. It takes the generated feature vectors and produces a confidence score as to whether the object is present in that particular region. As an extra step, a bounding box regressor is used to localize the objects which are present in the image more precisely.

The regressor is a scale-invariant linear regression model which precisely locates the bounding box in the image. This method sometimes results in extra bounding boxes which are handled by using a non-maximum suppression algorithm.

The algorithm discards objects whose confidence score falls below a set threshold value. Regions with the highest probability and don’t have an intersection over union with the predicted regions are selected.

In [ ]:
# Declarations

IMAGE_SIZE = 224
# Initialise the learning rate, epochs and batch size
RCNN_EPOCH = 5
batch_size = 8
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'

data = []
labels = []

Region of interest Extractor for positive and negative classes

  • Read the Dicom image and get the bounding box information for the CSV file.
  • Using this Bbox info, the image is cropped to get only the region of interest.
  • The cropped images are then resized to a standard size of 224x224, converted to arrays and then normalize the pixel values as required for the Pre-trained models.
  • Get a good balance of ROIs for both positive and negative classes.
In [ ]:
# Prepare Training data

train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
train_df.fillna(0,inplace=True)

# Functions to extract the bounding boxes and preprocess the image
def roiExtractor(row,patientId):
    dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
    img = dicom_data.pixel_array
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # Get the bounding box elements
    bb = [int(row['x']),int(row['y']),int(row['x']) + int(row['width']),int(row['y']) + int(row['height'])]
    # Crop the image
    roi = img[bb[1]:bb[3], bb[0]:bb[2]]
    # Reshape the image
    roi = cv2.resize(roi,(IMAGE_SIZE,IMAGE_SIZE),interpolation=cv2.INTER_CUBIC)
    # Convert the image to an array
    roi = img_to_array(roi)
    # Preprocess the image
    roi = preprocess_input(roi)
    return roi

pos_count = 0
neg_count = 0

# Looping through the excel sheet rows
for idx, row in train_df.iterrows():
    if (row['Target'] == 1) :
      if (pos_count <= 1000):
          roi = roiExtractor(row,row['patientId'])
          # Append the data and labels for the positive class
          data.append(roi)
          labels.append(int(1))
          pos_count += 1
    elif (neg_count <= 1000):
        dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % row['patientId']))
        img = dicom_data.pixel_array
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # Extract patches
        patches = extract_patches_2d(img,(128,128),max_patches=1)
        # For each patch do the augmentation
        for patch in patches:
            # Reshape the image
            roi = cv2.resize(patch,(IMAGE_SIZE,IMAGE_SIZE),interpolation=cv2.INTER_CUBIC)
            # Convert the image to an array
            roi = img_to_array(roi)
            # Preprocess the image
            roi = preprocess_input(roi)
            # Append the data into the data folder and labels folder
            neg_count += 1
            data.append(roi)
            labels.append(int(0))

#print('--'*40); print('Saving the feature engineered dataframe for future use'); print('--'*40)
#save_pickle(data, 'Milestone2_images_data.pkl')

Train and Test Data Preparation

  • Convert the data and labels into arrays and then perform one hot encoding to the labels for preparation of train and test sets.
  • Perform train and test split with 85:15 ratio.
In [ ]:
#data = open_pickle('Milestone2_images_data.pkl')

# convert the data and labels to NumPy arrays
data = np.array(data, dtype="float32")
labels = np.array(labels)
print(data.shape)
print(labels.shape)

# perform one-hot encoding on the labels
lb = LabelBinarizer()
# Fit transform the labels array
labels = lb.fit_transform(labels)
# Convert this to categorical
labels = to_categorical(labels)

# Partition data to train and test set with 85 : 15 split
(trainX, testX, trainY, testY) = train_test_split(data, labels,test_size=0.15, stratify=labels, random_state=42)
print("training data shape :",trainX.shape)
print("testing data shape :",testX.shape)
print("training labels shape :",trainY.shape)
print("testing labels shape :",testY.shape)


# Create a image generator with data augmentation
aug = ImageDataGenerator(
    rotation_range=40,
    zoom_range=0.25,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.30,
    horizontal_flip=True,
    fill_mode="nearest")


# Converting the target names as string for classification report
target_names = list(map(str,lb.classes_))
(2002, 224, 224, 3)
(2002,)
training data shape : (1701, 224, 224, 3)
testing data shape : (301, 224, 224, 3)
training labels shape : (1701, 2)
testing labels shape : (301, 2)

Training a Resnet50 model using transfer learning

  • Load the base network as the Resnet50.
  • Build our custom network on top of the output of the base network with final Dense layer using Softmax activation for 2 classes.
In [ ]:
def create_model_9() :
    model = ResNet50(weights="imagenet")
    x = model.output
    x = Flatten(name="flatten")(x)
    x = Dense(128, activation="relu")(x)
    x = Dropout(0.5)(x)
    predictions = Dense(2, activation="softmax")(x)
    model = Model(model.input, predictions)
    model.summary()
    model.compile(loss="binary_crossentropy", optimizer='adam', metrics=["accuracy"])
    return model

Model Prediction for pneumonia detection

  • The best model will be used to localise and predict pneumonia in test images.
  • Use Opencv to generate the bounding boxes proposals for the image.
  • Extract the region of interest from the image using the bounding boxes obtained from the selective search algorithm.
  • Classify the regions of proposal using the model fine tuned.
  • The model prediction gives us the probability of each class.
  • Apply non maxima suppression to reduce the number of bounding boxes.
In [ ]:
model_9 = create_model_9()
history_9 = model_9.fit(aug.flow(trainX, trainY, batch_size=32),steps_per_epoch=len(trainX) // 32,validation_data=(testX, testY),
                        validation_steps=len(testX) //32,epochs=20)
Model: "model_1"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 input_2 (InputLayer)           [(None, 224, 224, 3  0           []                               
                                )]                                                                
                                                                                                  
 conv1_pad (ZeroPadding2D)      (None, 230, 230, 3)  0           ['input_2[0][0]']                
                                                                                                  
 conv1_conv (Conv2D)            (None, 112, 112, 64  9472        ['conv1_pad[0][0]']              
                                )                                                                 
                                                                                                  
 conv1_bn (BatchNormalization)  (None, 112, 112, 64  256         ['conv1_conv[0][0]']             
                                )                                                                 
                                                                                                  
 conv1_relu (Activation)        (None, 112, 112, 64  0           ['conv1_bn[0][0]']               
                                )                                                                 
                                                                                                  
 pool1_pad (ZeroPadding2D)      (None, 114, 114, 64  0           ['conv1_relu[0][0]']             
                                )                                                                 
                                                                                                  
 pool1_pool (MaxPooling2D)      (None, 56, 56, 64)   0           ['pool1_pad[0][0]']              
                                                                                                  
 conv2_block1_1_conv (Conv2D)   (None, 56, 56, 64)   4160        ['pool1_pool[0][0]']             
                                                                                                  
 conv2_block1_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block1_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block1_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block1_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block1_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block1_1_relu[0][0]']    
                                                                                                  
 conv2_block1_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block1_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block1_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block1_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block1_0_conv (Conv2D)   (None, 56, 56, 256)  16640       ['pool1_pool[0][0]']             
                                                                                                  
 conv2_block1_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block1_2_relu[0][0]']    
                                                                                                  
 conv2_block1_0_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block1_0_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block1_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block1_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block1_add (Add)         (None, 56, 56, 256)  0           ['conv2_block1_0_bn[0][0]',      
                                                                  'conv2_block1_3_bn[0][0]']      
                                                                                                  
 conv2_block1_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block1_add[0][0]']       
                                                                                                  
 conv2_block2_1_conv (Conv2D)   (None, 56, 56, 64)   16448       ['conv2_block1_out[0][0]']       
                                                                                                  
 conv2_block2_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block2_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block2_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block2_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block2_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block2_1_relu[0][0]']    
                                                                                                  
 conv2_block2_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block2_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block2_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block2_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block2_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block2_2_relu[0][0]']    
                                                                                                  
 conv2_block2_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block2_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block2_add (Add)         (None, 56, 56, 256)  0           ['conv2_block1_out[0][0]',       
                                                                  'conv2_block2_3_bn[0][0]']      
                                                                                                  
 conv2_block2_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block2_add[0][0]']       
                                                                                                  
 conv2_block3_1_conv (Conv2D)   (None, 56, 56, 64)   16448       ['conv2_block2_out[0][0]']       
                                                                                                  
 conv2_block3_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block3_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block3_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block3_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block3_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block3_1_relu[0][0]']    
                                                                                                  
 conv2_block3_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block3_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block3_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block3_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv2_block3_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block3_2_relu[0][0]']    
                                                                                                  
 conv2_block3_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block3_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv2_block3_add (Add)         (None, 56, 56, 256)  0           ['conv2_block2_out[0][0]',       
                                                                  'conv2_block3_3_bn[0][0]']      
                                                                                                  
 conv2_block3_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block3_add[0][0]']       
                                                                                                  
 conv3_block1_1_conv (Conv2D)   (None, 28, 28, 128)  32896       ['conv2_block3_out[0][0]']       
                                                                                                  
 conv3_block1_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block1_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block1_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block1_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block1_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block1_1_relu[0][0]']    
                                                                                                  
 conv3_block1_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block1_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block1_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block1_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block1_0_conv (Conv2D)   (None, 28, 28, 512)  131584      ['conv2_block3_out[0][0]']       
                                                                                                  
 conv3_block1_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block1_2_relu[0][0]']    
                                                                                                  
 conv3_block1_0_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block1_0_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block1_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block1_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block1_add (Add)         (None, 28, 28, 512)  0           ['conv3_block1_0_bn[0][0]',      
                                                                  'conv3_block1_3_bn[0][0]']      
                                                                                                  
 conv3_block1_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block1_add[0][0]']       
                                                                                                  
 conv3_block2_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block1_out[0][0]']       
                                                                                                  
 conv3_block2_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block2_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block2_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block2_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block2_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block2_1_relu[0][0]']    
                                                                                                  
 conv3_block2_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block2_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block2_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block2_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block2_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block2_2_relu[0][0]']    
                                                                                                  
 conv3_block2_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block2_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block2_add (Add)         (None, 28, 28, 512)  0           ['conv3_block1_out[0][0]',       
                                                                  'conv3_block2_3_bn[0][0]']      
                                                                                                  
 conv3_block2_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block2_add[0][0]']       
                                                                                                  
 conv3_block3_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block2_out[0][0]']       
                                                                                                  
 conv3_block3_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block3_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block3_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block3_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block3_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block3_1_relu[0][0]']    
                                                                                                  
 conv3_block3_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block3_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block3_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block3_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block3_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block3_2_relu[0][0]']    
                                                                                                  
 conv3_block3_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block3_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block3_add (Add)         (None, 28, 28, 512)  0           ['conv3_block2_out[0][0]',       
                                                                  'conv3_block3_3_bn[0][0]']      
                                                                                                  
 conv3_block3_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block3_add[0][0]']       
                                                                                                  
 conv3_block4_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block3_out[0][0]']       
                                                                                                  
 conv3_block4_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block4_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block4_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block4_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block4_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block4_1_relu[0][0]']    
                                                                                                  
 conv3_block4_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block4_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block4_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block4_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv3_block4_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block4_2_relu[0][0]']    
                                                                                                  
 conv3_block4_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block4_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv3_block4_add (Add)         (None, 28, 28, 512)  0           ['conv3_block3_out[0][0]',       
                                                                  'conv3_block4_3_bn[0][0]']      
                                                                                                  
 conv3_block4_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block4_add[0][0]']       
                                                                                                  
 conv4_block1_1_conv (Conv2D)   (None, 14, 14, 256)  131328      ['conv3_block4_out[0][0]']       
                                                                                                  
 conv4_block1_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block1_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block1_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block1_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block1_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block1_1_relu[0][0]']    
                                                                                                  
 conv4_block1_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block1_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block1_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block1_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block1_0_conv (Conv2D)   (None, 14, 14, 1024  525312      ['conv3_block4_out[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block1_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block1_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block1_0_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block1_0_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block1_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block1_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block1_add (Add)         (None, 14, 14, 1024  0           ['conv4_block1_0_bn[0][0]',      
                                )                                 'conv4_block1_3_bn[0][0]']      
                                                                                                  
 conv4_block1_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block1_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block2_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block1_out[0][0]']       
                                                                                                  
 conv4_block2_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block2_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block2_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block2_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block2_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block2_1_relu[0][0]']    
                                                                                                  
 conv4_block2_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block2_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block2_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block2_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block2_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block2_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block2_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block2_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block2_add (Add)         (None, 14, 14, 1024  0           ['conv4_block1_out[0][0]',       
                                )                                 'conv4_block2_3_bn[0][0]']      
                                                                                                  
 conv4_block2_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block2_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block3_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block2_out[0][0]']       
                                                                                                  
 conv4_block3_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block3_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block3_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block3_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block3_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block3_1_relu[0][0]']    
                                                                                                  
 conv4_block3_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block3_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block3_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block3_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block3_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block3_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block3_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block3_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block3_add (Add)         (None, 14, 14, 1024  0           ['conv4_block2_out[0][0]',       
                                )                                 'conv4_block3_3_bn[0][0]']      
                                                                                                  
 conv4_block3_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block3_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block4_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block3_out[0][0]']       
                                                                                                  
 conv4_block4_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block4_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block4_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block4_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block4_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block4_1_relu[0][0]']    
                                                                                                  
 conv4_block4_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block4_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block4_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block4_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block4_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block4_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block4_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block4_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block4_add (Add)         (None, 14, 14, 1024  0           ['conv4_block3_out[0][0]',       
                                )                                 'conv4_block4_3_bn[0][0]']      
                                                                                                  
 conv4_block4_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block4_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block5_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block4_out[0][0]']       
                                                                                                  
 conv4_block5_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block5_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block5_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block5_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block5_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block5_1_relu[0][0]']    
                                                                                                  
 conv4_block5_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block5_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block5_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block5_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block5_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block5_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block5_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block5_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block5_add (Add)         (None, 14, 14, 1024  0           ['conv4_block4_out[0][0]',       
                                )                                 'conv4_block5_3_bn[0][0]']      
                                                                                                  
 conv4_block5_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block5_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv4_block6_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block5_out[0][0]']       
                                                                                                  
 conv4_block6_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block6_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block6_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block6_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block6_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block6_1_relu[0][0]']    
                                                                                                  
 conv4_block6_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block6_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv4_block6_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block6_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv4_block6_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block6_2_relu[0][0]']    
                                )                                                                 
                                                                                                  
 conv4_block6_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block6_3_conv[0][0]']    
 ization)                       )                                                                 
                                                                                                  
 conv4_block6_add (Add)         (None, 14, 14, 1024  0           ['conv4_block5_out[0][0]',       
                                )                                 'conv4_block6_3_bn[0][0]']      
                                                                                                  
 conv4_block6_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block6_add[0][0]']       
                                )                                                                 
                                                                                                  
 conv5_block1_1_conv (Conv2D)   (None, 7, 7, 512)    524800      ['conv4_block6_out[0][0]']       
                                                                                                  
 conv5_block1_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block1_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block1_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block1_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block1_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block1_1_relu[0][0]']    
                                                                                                  
 conv5_block1_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block1_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block1_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block1_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block1_0_conv (Conv2D)   (None, 7, 7, 2048)   2099200     ['conv4_block6_out[0][0]']       
                                                                                                  
 conv5_block1_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block1_2_relu[0][0]']    
                                                                                                  
 conv5_block1_0_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block1_0_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block1_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block1_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block1_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block1_0_bn[0][0]',      
                                                                  'conv5_block1_3_bn[0][0]']      
                                                                                                  
 conv5_block1_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block1_add[0][0]']       
                                                                                                  
 conv5_block2_1_conv (Conv2D)   (None, 7, 7, 512)    1049088     ['conv5_block1_out[0][0]']       
                                                                                                  
 conv5_block2_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block2_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block2_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block2_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block2_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block2_1_relu[0][0]']    
                                                                                                  
 conv5_block2_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block2_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block2_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block2_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block2_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block2_2_relu[0][0]']    
                                                                                                  
 conv5_block2_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block2_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block2_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block1_out[0][0]',       
                                                                  'conv5_block2_3_bn[0][0]']      
                                                                                                  
 conv5_block2_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block2_add[0][0]']       
                                                                                                  
 conv5_block3_1_conv (Conv2D)   (None, 7, 7, 512)    1049088     ['conv5_block2_out[0][0]']       
                                                                                                  
 conv5_block3_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block3_1_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block3_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block3_1_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block3_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block3_1_relu[0][0]']    
                                                                                                  
 conv5_block3_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block3_2_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block3_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block3_2_bn[0][0]']      
 n)                                                                                               
                                                                                                  
 conv5_block3_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block3_2_relu[0][0]']    
                                                                                                  
 conv5_block3_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block3_3_conv[0][0]']    
 ization)                                                                                         
                                                                                                  
 conv5_block3_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block2_out[0][0]',       
                                                                  'conv5_block3_3_bn[0][0]']      
                                                                                                  
 conv5_block3_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block3_add[0][0]']       
                                                                                                  
 avg_pool (GlobalAveragePooling  (None, 2048)        0           ['conv5_block3_out[0][0]']       
 2D)                                                                                              
                                                                                                  
 predictions (Dense)            (None, 1000)         2049000     ['avg_pool[0][0]']               
                                                                                                  
 flatten (Flatten)              (None, 1000)         0           ['predictions[0][0]']            
                                                                                                  
 dense_2 (Dense)                (None, 128)          128128      ['flatten[0][0]']                
                                                                                                  
 dropout_1 (Dropout)            (None, 128)          0           ['dense_2[0][0]']                
                                                                                                  
 dense_3 (Dense)                (None, 2)            258         ['dropout_1[0][0]']              
                                                                                                  
==================================================================================================
Total params: 25,765,098
Trainable params: 25,711,978
Non-trainable params: 53,120
__________________________________________________________________________________________________
Epoch 1/20
53/53 [==============================] - 60s 425ms/step - loss: 0.6505 - accuracy: 0.7406 - val_loss: 0.7056 - val_accuracy: 0.4983
Epoch 2/20
53/53 [==============================] - 21s 402ms/step - loss: 0.6037 - accuracy: 0.7058 - val_loss: 0.7087 - val_accuracy: 0.4983
Epoch 3/20
53/53 [==============================] - 21s 389ms/step - loss: 0.5682 - accuracy: 0.6872 - val_loss: 0.6941 - val_accuracy: 0.5515
Epoch 4/20
53/53 [==============================] - 21s 402ms/step - loss: 0.5636 - accuracy: 0.7124 - val_loss: 0.8896 - val_accuracy: 0.4983
Epoch 5/20
53/53 [==============================] - 21s 399ms/step - loss: 0.5020 - accuracy: 0.7633 - val_loss: 0.7580 - val_accuracy: 0.5083
Epoch 6/20
53/53 [==============================] - 21s 392ms/step - loss: 0.5396 - accuracy: 0.7322 - val_loss: 0.7110 - val_accuracy: 0.4884
Epoch 7/20
53/53 [==============================] - 21s 400ms/step - loss: 0.4802 - accuracy: 0.7819 - val_loss: 1.1416 - val_accuracy: 0.5017
Epoch 8/20
53/53 [==============================] - 21s 401ms/step - loss: 0.4356 - accuracy: 0.8125 - val_loss: 0.6848 - val_accuracy: 0.4850
Epoch 9/20
53/53 [==============================] - 22s 406ms/step - loss: 0.4469 - accuracy: 0.7927 - val_loss: 0.8004 - val_accuracy: 0.4983
Epoch 10/20
53/53 [==============================] - 21s 399ms/step - loss: 0.4173 - accuracy: 0.8167 - val_loss: 0.7992 - val_accuracy: 0.4983
Epoch 11/20
53/53 [==============================] - 22s 407ms/step - loss: 0.4578 - accuracy: 0.7983 - val_loss: 1.1477 - val_accuracy: 0.4983
Epoch 12/20
53/53 [==============================] - 21s 385ms/step - loss: 0.3892 - accuracy: 0.8256 - val_loss: 1.0411 - val_accuracy: 0.5349
Epoch 13/20
53/53 [==============================] - 21s 398ms/step - loss: 0.3868 - accuracy: 0.8280 - val_loss: 0.6298 - val_accuracy: 0.6910
Epoch 14/20
53/53 [==============================] - 21s 391ms/step - loss: 0.3989 - accuracy: 0.8346 - val_loss: 0.9432 - val_accuracy: 0.5781
Epoch 15/20
53/53 [==============================] - 21s 399ms/step - loss: 0.4010 - accuracy: 0.8214 - val_loss: 1.1858 - val_accuracy: 0.4485
Epoch 16/20
53/53 [==============================] - 21s 396ms/step - loss: 0.3563 - accuracy: 0.8616 - val_loss: 1.3935 - val_accuracy: 0.5814
Epoch 17/20
53/53 [==============================] - 21s 393ms/step - loss: 0.3653 - accuracy: 0.8430 - val_loss: 1.1004 - val_accuracy: 0.6113
Epoch 18/20
53/53 [==============================] - 21s 404ms/step - loss: 0.3568 - accuracy: 0.8478 - val_loss: 0.7895 - val_accuracy: 0.5714
Epoch 19/20
53/53 [==============================] - 21s 394ms/step - loss: 0.3304 - accuracy: 0.8628 - val_loss: 0.8945 - val_accuracy: 0.6412
Epoch 20/20
53/53 [==============================] - 21s 400ms/step - loss: 0.3971 - accuracy: 0.8304 - val_loss: 1.2770 - val_accuracy: 0.6346
In [ ]:
def maxOverlap(boxes):
    '''
    boxes : This is the cordinates of the boxes which have the object
    returns : A list of boxes which do not have much overlap
    '''
    # Convert the bounding boxes into an array
    boxes = np.array(boxes)
    # Initialise a box to pick the ids of the selected boxes and include the largest box
    selected = []
    # Continue the loop till the number of ids remaining in the box is greater than 1
    while len(boxes) > 1:
        # First calculate the area of the bounding boxes
        x1 = boxes[:, 0]
        y1 = boxes[:, 1]
        x2 = boxes[:, 2]
        y2 = boxes[:, 3]
        area = (x2 - x1) * (y2 - y1)
        # Sort the bounding boxes based on its area
        ids = np.argsort(area)
        #print('ids',ids)
        # Take the coordinates of the box with the largest area
        lx1 = boxes[ids[-1], 0]
        ly1 = boxes[ids[-1], 1]
        lx2 = boxes[ids[-1], 2]
        ly2 = boxes[ids[-1], 3]
        # Include the largest box into the selected list
        selected.append(boxes[ids[-1]].tolist())
        # Initialise a list for getting those ids that needs to be removed.
        remove = []
        remove.append(ids[-1])
        # We loop through each of the other boxes and find the overlap of the boxes with the largest box
        for id in ids[:-1]:
            #print('id',id)
            # The maximum of the starting x cordinate is where the overlap along width starts
            ox1 = np.maximum(lx1, boxes[id,0])
            # The maximum of the starting y cordinate is where the overlap along height starts
            oy1 = np.maximum(ly1, boxes[id,1])
            # The minimum of the ending x cordinate is where the overlap along width ends
            ox2 = np.minimum(lx2, boxes[id,2])
            # The minimum of the ending y cordinate is where the overlap along height ends
            oy2 = np.minimum(ly2, boxes[id,3])
            # Find area of the overlapping coordinates
            oa = (ox2 - ox1) * (oy2 - oy1)
            # Find the ratio of overlapping area of the smaller box with respect to its original area
            olRatio = oa/area[id]
            # If the overlap is greater than threshold include the id in the remove list
            if olRatio > 0.40:
                remove.append(id)
        # Remove those ids from the original boxes
        boxes = np.delete(boxes, remove,axis = 0)
        # Break the while loop if nothing to remove
        if len(remove) == 0:
            break
    # Append the remaining boxes to the selected
    for i in range(len(boxes)):
        selected.append(boxes[i].tolist())
    return np.array(selected)

# Function to show an image with actual bounding box coordinates
def show_image_with_bboxes(patientId):
    # Create a plot
    f, ax = plt.subplots(figsize=(5, 5))
    ID = "Actual: ",format(patientId)
    orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
    image = orig_image.pixel_array
    plt.imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
    plt.title(ID)
    # Copy all the rows where the patientId matches
    filter = train_df[train_df['patientId'] == patientId]
    # Collect data from all entries for a given patientId
    for j, filtered_row in enumerate(list(filter.T.to_dict().values())):
        x, y, width, height = filtered_row['x'], filtered_row['y'], filtered_row['width'], filtered_row['height']
        rectangle = Rectangle(xy=(x,y),width=width, height=height, color="red",alpha = 0.2)
        ax.add_patch(rectangle)

# make predictions on the test set
def predict_model(model, history, patientId):
    predictions = model.predict(testX, batch_size=32)
    # For each prediction we need to find the index with maximum probability
    predIdxs = np.argmax(predictions, axis=1)
    # Print the classification report
    print(classification_report(testY.argmax(axis=1), predIdxs,target_names=target_names ,zero_division=0))

    # plot the training loss and accuracy
    N = 20
    plt.style.use("ggplot")
    plt.figure()
    plt.plot(np.arange(0, N), history.history["loss"], label="train_loss")
    plt.plot(np.arange(0, N), history.history["accuracy"], label="train_acc")
    plt.title("Training Loss and Accuracy")
    plt.xlabel("Epoch #")
    plt.ylabel("Loss/Accuracy")
    plt.legend(loc="lower left")
    plt.savefig("plot.png")
    plt.show()

    # Implementing selective search to generate bounding box proposals
    dicom_data = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
    img = dicom_data.pixel_array
    img = cv2.resize(img, (224, 224))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
    ss.setBaseImage(img)
    #ss.switchToSelectiveSearchFast()
    ss.switchToSelectiveSearchQuality()
    rects = ss.process()

    # Initialise lists to store the region of interest from the image and its bounding boxes
    proposals = []
    boxes = []
    max_proposals = 100
    # Iterate over the bounding box coordinates to extract region of interest from image
    for (x, y, w, h) in rects[:max_proposals]:
        # if the width or height of the region is more than 40% of the
        # image width or height, ignore it (i.e., filter out large
        # objects that are likely false-positives)
        if w / 224 > 0.2 or h / 224 > 0.2:
            continue
        # Crop region of interest from the image
        roi = img[y:y + h, x:x + w]
        # Convert to RGB format as CV2 has output in BGR format
        roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
        # Resize image to our standar size
        roi = cv2.resize(roi, (224,224), interpolation=cv2.INTER_CUBIC)
        # Preprocess the image
        roi = img_to_array(roi)
        roi = preprocess_input(roi)
        # Update the proposal and bounding boxes
        proposals.append(roi)
        boxes.append((x, y, x + w, y + h))

    # Convert proposals and bouding boxes to NumPy arrays
    proposals = np.array(proposals, dtype="float32")
    boxes = np.array(boxes, dtype="int32")
    # Classify the proposals based on the fine tuned model
    proba = model.predict(proposals)

    # Find the predicted labels
    labels = lb.classes_[np.argmax(proba, axis=1)]
    # Get the ids where the predictions are 'pneumonia'
    idxs = np.where(labels == 1)[0]
    # Using the indexes, extract the bounding boxes and prediction probabilities of 'pneumonia' class
    boxes = boxes[idxs]
    proba = proba[idxs][:, 1]

    # Filter the bounding boxes using a prediction probability threshold
    pred_threshold = 0.995
    # Select only those ids where the probability is greater than the threshold
    idxs = np.where(proba >= pred_threshold)
    boxes = boxes[idxs]
    proba = proba[idxs]

    # Clone the original image for visualisation and inserting text
    clone = img.copy()
    # Iterate through the bounding boxes and associated probabilities
    for (box, prob) in zip(boxes, proba):
        # Draw the bounding box, label, and probability on the image
        (startX, startY, endX, endY) = box
        cv2.rectangle(clone, (startX, startY), (endX, endY),(0, 255, 0), 2)
        # Initialising the cordinate for writing the text
        y = startY - 10 if startY - 10 > 10 else startY + 10
        # Getting the text to be attached on top of the box
        text= "Pneumonia: {:.2f}%".format(prob * 100)
        # Visualise the text on the image
        cv2.putText(clone, text, (startX, y),cv2.FONT_HERSHEY_SIMPLEX, 0.25, (0, 255, 0), 1)
    # Visualise the bounding boxes on the image
    plt.imshow(clone,aspect='equal')
    plt.show()

    # Applying non maxima suppression
    selected = maxOverlap(boxes)

    clone = img.copy()
    plt.imshow(img,aspect='equal')
    for (startX, startY, endX, endY) in selected:
        cv2.rectangle(clone, (startX, startY), (endX, endY), (0, 255, 0), 2)
    plt.imshow(clone,aspect='equal')
    plt.title("Predicted Image")
    plt.show()

    # SHow the actual image for comparision
    # Function to show an image with actual bounding box coordinates
    show_image_with_bboxes(patientId)
In [ ]:
patientId = '76f71a93-8105-4c79-a010-0cfa86f0061a'
predict_model(model_9, history_9, patientId)
10/10 [==============================] - 1s 56ms/step
              precision    recall  f1-score   support

           0       0.79      0.36      0.50       150
           1       0.59      0.91      0.71       151

    accuracy                           0.63       301
   macro avg       0.69      0.63      0.60       301
weighted avg       0.69      0.63      0.60       301

2/2 [==============================] - 0s 48ms/step

Observation

• Preprocessed the positive and negative classes of images and then built our train and test sets

• Fine tuned the Resnet50 model to cater to our use case and made it our classifier.

• Built the inference pipeline using the fine tuned classifier

• Applied non maxima suppression to get the bounding boxes over the pneumonia region.

• Overall 69% Average accuracy is achieved with this model.

• The precision to identify positive Pneumonia cases is less (59%).

• Model has higher recall (91%) and higher F1 score (71%) for class 1.

• Selective search algorithm has its own disadvantages. Since this is a very basic model and many new improved versions of RCNN are available, it is better to try out those models for Object detection.

Advantages and Applications of RCNN

Object localization and object detection are the two core operations in computer vision and therefore have a lot of real-world applications in a variety of fields. It is used in autonomous vehicles for perceiving objects in their surroundings to ensure a safe driving experience. In the field of construction, RCNN can be used for maintenance work like analyzing high-resolution pictures of rust In the manufacturing industry, RCNN can be used for defective product identification and automated inspections. Generally, since the base model of RCNN does not have the performance needed for real-time application, models built on this base such as Fast-RCNN, Faster RCNN, or mask RCNN are used. All these variations try to improvise the testing and the analysis of the generated region proposals.

Disadvantages of RCNN

The selective search algorithm is very rigid. Since it’s a fixed algorithm no learning happens during the search. This sometimes could result in the generation of bad region proposals. It is very time-consuming since the number of region proposals is approximately 2000 or more. Multiple steps in the RCNN architecture have to be trained separately. Hence the implementation of the model is very slow. Real-time application is not possible due to the amount of time it takes to test images. Feature maps of the region proposals need to be saved. This increases the amount of memory space needed during training.

Regional Convolutional Neural Network is an object detection algorithm hence it is quite different from image classification. This led to more efficient models built on top of the base RCNN model which improves efficiency and speed. It helped deal with a lot of problems CNN faced in terms of multi-objects and finding the location of the objects in the image. It led to a lot of variations built on top of this technology and is one of the core technology used in emerging fields like computer vision.

2. Faster RCNN Neural Network Model for Object Detection¶

What is Faster-RCNN? Faster R-CNN is an object detection algorithm proposed by Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun in 2015. Faster R-CNN is an object detection model that improves on Fast R-CNN by utilising a region proposal network (RPN) with the CNN model. The RPN shares full-image convolutional features with the detection network, enabling region proposals. It is a fully convolutional network that simultaneously predicts object bounds and objectness scores at each position.

The RPN is trained end-to-end to generate high-quality region proposals, which are used by Fast R-CNN for detection. RPN and Fast R-CNN are merged into a single network by sharing their convolutional features: the RPN component tells the unified network where to look.

Faster R-CNN consists of two modules. The first module is a deep fully convolutional network that proposes regions, and the second module is the Fast R-CNN detector that uses the proposed regions.

Defining the adjusted image size to 224 to help train the model faster and accordingly defined FACTOR variable to resize the bounding box data from train set

Used 3 different approaches with varying image size to train the model.

1) Original image size with single channel - predicted results were good however it was taking long to train.

2) Resized actual image to 128 X 128 X 3 - took less training time however prediction was less accurate.

3) Current Optimal Approach: Resized actual image to 224 X 224 X 3 - In this case, the training time has reduced significantly and prediction results have also improved.

Train and Test Data Preparation

Loading the “stage_2_train_labels.csv” file into pandas dataframe

• patientId – which refers to the patientId’s corresponding image name

• x - upper-left x coordinate of the bounding box

• y - upper-left y coordinate of the bounding box

• width – the width of the bounding box

• height – the height of the bounding box

• Target – binary target indicating if this image has evidence of pneumonia

There is a total of 30,227 entries, no missing values with 9,555 images have bounding boxes.

In our solution, as we use Faster R-CNN object detector with PyTorch

In [ ]:
# Read the CSV file
train_df = pd.read_csv('/kaggle/input/pneumonia-dataset/stage_2_train_labels.csv')
In [ ]:
IMAGE_PATH = '/kaggle/input/pneumonia-dataset/stage_2_train_images/stage_2_train_images/'
In [ ]:
IMAGE_SIZE = 1024 #sample_pixel_array.shape[0]
ADJUSTED_IMAGE_SIZE=224
FACTOR = ADJUSTED_IMAGE_SIZE/IMAGE_SIZE
In [ ]:
train_df.fillna(0,inplace=True)
In [ ]:
train_df['x']            = train_df['x'].astype('int');
train_df['y']            = train_df['y'].astype('int');
train_df['width']        = train_df['width'].astype('int');
train_df['height']       = train_df['height'].astype('int');
In [ ]:
print('Original dataframe shape:', train_df.shape)

train_labels_df_pos = pd.DataFrame(columns=['patientId', 'x', 'y', 'width', 'height'])

k = 0
for i in range(len(train_df)):
    if train_df.iloc[i]['Target'] == 1:
        train_labels_df_pos.loc[k] = train_df.loc[i]
        k += 1

print('Positive instances dataframe shape:', train_labels_df_pos.shape)
#train_paths = [os.path.join(IMAGE_PATH, image[0]) for image in train_labels_df_pos.values]
Original dataframe shape: (30227, 6)

Positive instances dataframe shape: (9555, 5)
In [ ]:
train_labels_df_pos['x']            = train_labels_df_pos['x'].astype('int');
train_labels_df_pos['y']            = train_labels_df_pos['y'].astype('int');
train_labels_df_pos['width']        = train_labels_df_pos['width'].astype('int');
train_labels_df_pos['height']       = train_labels_df_pos['height'].astype('int');

Using PyTorch Dataset and DataLoader

In PyTorch, it’s considered a best practice to create a class that inherits from PyTorch’s Dataset class to load the data. This will give us more control over the data and helps keep the code modular.

In class PneumoniaDataset, we’ve defined a function called get_item that loads the images, labelled classes, and bounding box coordinates which are then converted to PyTorch’s Tensor object. The images are reshaped to a fixed size (224 X224 X 3).

We further use the PyTorch DataLoader for the dataset instance to took care of batching, shuffling, and sampling of the train and valid dataset.

We will use the pre-trained model included with torchvision.

• Downloading the Faster R-CNN Resnet50 FPN V2 model with pretrained weights on 167M images.

• We set the desired num_classes as ‘2’

In [ ]:
class PneumoniaDataset(Dataset):
    def __init__(self, dataframe, image_dir, transforms=None):
        super().__init__()

        self.image_ids = dataframe['patientId'].unique()
        self.df = dataframe
        self.image_dir = image_dir
        self.transforms = transforms

    def __getitem__(self, index):
        # load images and bounding boxes
        image_id = self.image_ids[index]
        records = self.df[self.df['patientId'] == image_id]

        dicom_data = pydicom.read_file(os.path.join(self.image_dir + '%s.dcm' % image_id))

        img = dicom_data.pixel_array
        img = cv2.resize(img, (ADJUSTED_IMAGE_SIZE, ADJUSTED_IMAGE_SIZE))

        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)
        img /= 255.0
        boxes = records[['x', 'y', 'width', 'height']].values
        boxes[:, 2] = boxes[:, 0] + boxes[:, 2]
        boxes[:, 3] = boxes[:, 1] + boxes[:, 3]

        #Resizing
        boxes[:, 0]=boxes[:, 0].astype(np.int32)* FACTOR
        boxes[:, 1]=boxes[:, 1].astype(np.int32)* FACTOR
        boxes[:, 2]=boxes[:, 2].astype(np.int32)* FACTOR
        boxes[:, 3]=boxes[:, 3].astype(np.int32)* FACTOR
        boxes=np.vstack(boxes).astype(np.float32)
        #print("Final co:")
        #print(boxes[:,0],boxes[:,2],boxes[:,1],boxes[:,3])
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
        area = np.vstack(area).astype(np.float32)
        area = torch.as_tensor(area, dtype=torch.float32)


        # there is only one class
        labels = torch.ones((records.shape[0],), dtype=torch.int64)
        # suppose all instances are not crowd
        iscrowd = torch.zeros((records.shape[0],), dtype=torch.int64)

        target = {}
        target['boxes'] = boxes
        target['labels'] = labels
        target['patientId'] = torch.tensor([index])
        target['area'] = area
        target['iscrowd'] = iscrowd

        if self.transforms:
            sample = {
                'image': img,
                'bboxes': target['boxes'],
                'labels': labels
            }
            sample = self.transforms(**sample)
            img = sample['image']

            target['boxes'] = torch.stack(tuple(map(torch.FloatTensor, zip(*sample['bboxes'])))).permute(1, 0)

        return img, target


    def __len__(self):
        return self.image_ids.shape[0]

# Albumentations
def get_train_transform():
    return A.Compose([
        A.Resize(width=ADJUSTED_IMAGE_SIZE,height=ADJUSTED_IMAGE_SIZE),
        A.Flip(0.5),
        A.RandomRotate90(0.5),
        A.MotionBlur(p=0.2),
        A.MedianBlur(blur_limit=3, p=0.1),
        A.Blur(blur_limit=3, p=0.1),
        ToTensorV2(p=1.0)
    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})

def get_valid_transform():
    return A.Compose([
        A.Resize(width=ADJUSTED_IMAGE_SIZE,height=ADJUSTED_IMAGE_SIZE),
        ToTensorV2(p=1.0)
    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
def collate_fn(batch):
    return tuple(zip(*batch))

class Averager:
    def __init__(self):
        self.current_total = 0.0
        self.iterations = 0.0

    def send(self, value):
        self.current_total += value
        self.iterations += 1

    @property
    def value(self):
        if self.iterations == 0:
            return 0
        else:
            return 1.0 * self.current_total / self.iterations

    def reset(self):
        self.current_total = 0.0
        self.iterations = 0.0
In [ ]:
image_ids = train_labels_df_pos['patientId'].unique()
valid_ids = image_ids[-300:]
train_ids = image_ids[:-300]
print(f"Training instance: {len(train_ids)}")
print(f"Validation instances: {len(valid_ids)}")

valid_df = train_labels_df_pos[train_labels_df_pos['patientId'].isin(valid_ids)]
train_df = train_labels_df_pos[train_labels_df_pos['patientId'].isin(train_ids)]

print('Train dataframe shape:', train_df.shape)
print('Valid dataframe shape:', valid_df.shape)

train_dataset = PneumoniaDataset(train_df, IMAGE_PATH, get_train_transform())
valid_dataset = PneumoniaDataset(valid_df, IMAGE_PATH, get_valid_transform())
print('train_dataset and valid_dataset are loaded :)')
print("We have: {} training examples and {} validation examples".format(len(train_dataset), len(valid_dataset)))

train_data_loader = DataLoader(train_dataset, batch_size=8, shuffle=False, num_workers=2, collate_fn=collate_fn)
valid_data_loader = DataLoader(valid_dataset, batch_size=8, shuffle=False, num_workers=2, collate_fn=collate_fn)
Training instance: 5712

Validation instances: 300

Train dataframe shape: (9057, 5)

Valid dataframe shape: (498, 5)

train_dataset and valid_dataset are loaded :)

We have: 5712 training examples and 300 validation examples
In [ ]:
def calculate_image_precision(gts, preds, thresholds = (0.5, ), form = 'coco') -> float:
    # https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
    """Calculates image precision.

    Args:
        gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
        preds: (List[List[Union[int, float]]]) Coordinates of the predicted boxes,
               sorted by confidence value (descending)
        thresholds: (float) Different thresholds
        form: (str) Format of the coordinates

    Return:
        (float) Precision
    """
    n_threshold = len(thresholds)
    image_precision = 0.0

    ious = np.ones((len(gts), len(preds))) * -1
    # ious = None

    for threshold in thresholds:
        precision_at_threshold = calculate_precision(gts.copy(), preds, threshold=threshold,
                                                     form=form, ious=ious)
        image_precision += precision_at_threshold / n_threshold

    return image_precision


def calculate_iou(gt, pr, form='pascal_voc') -> float:
    # https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
    """Calculates the Intersection over Union.

    Args:
        gt: (np.ndarray[Union[int, float]]) coordinates of the ground-truth box
        pr: (np.ndarray[Union[int, float]]) coordinates of the prdected box
        form: (str) gt/pred coordinates format
            - pascal_voc: [xmin, ymin, xmax, ymax]
            - coco: [xmin, ymin, w, h]
    Returns:
        (float) Intersection over union (0.0 <= iou <= 1.0)
    """
    if form == 'coco':
        gt = gt.copy()
        pr = pr.copy()

        gt[2] = gt[0] + gt[2]
        gt[3] = gt[1] + gt[3]
        pr[2] = pr[0] + pr[2]
        pr[3] = pr[1] + pr[3]

    # Calculate overlap area
    dx = min(gt[2], pr[2]) - max(gt[0], pr[0]) + 1

    if dx < 0:
        return 0.0
    dy = min(gt[3], pr[3]) - max(gt[1], pr[1]) + 1

    if dy < 0:
        return 0.0

    overlap_area = dx * dy

    # Calculate union area
    union_area = (
            (gt[2] - gt[0] + 1) * (gt[3] - gt[1] + 1) +
            (pr[2] - pr[0] + 1) * (pr[3] - pr[1] + 1) -
            overlap_area
    )

    return overlap_area / union_area


def find_best_match(gts, pred, pred_idx, threshold = 0.5, form = 'pascal_voc', ious=None) -> int:
    # https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
    """Returns the index of the 'best match' between the
    ground-truth boxes and the prediction. The 'best match'
    is the highest IoU. (0.0 IoUs are ignored).

    Args:
        gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
        pred: (List[Union[int, float]]) Coordinates of the predicted box
        pred_idx: (int) Index of the current predicted box
        threshold: (float) Threshold
        form: (str) Format of the coordinates
        ious: (np.ndarray) len(gts) x len(preds) matrix for storing calculated ious.

    Return:
        (int) Index of the best match GT box (-1 if no match above threshold)
    """
    best_match_iou = -np.inf
    best_match_idx = -1
    for gt_idx in range(len(gts)):

        if gts[gt_idx][0] < 0:
            # Already matched GT-box
            continue

        iou = -1 if ious is None else ious[gt_idx][pred_idx]

        if iou < 0:
            iou = calculate_iou(gts[gt_idx], pred, form=form)

            if ious is not None:
                ious[gt_idx][pred_idx] = iou

        if iou < threshold:
            continue

        if iou > best_match_iou:
            best_match_iou = iou
            best_match_idx = gt_idx

    return best_match_idx

def calculate_precision(gts, preds, threshold = 0.5, form = 'coco', ious=None) -> float:
    # https://www.kaggle.com/sadmanaraf/wheat-detection-using-faster-rcnn-train
    """Calculates precision for GT - prediction pairs at one threshold.

    Args:
        gts: (List[List[Union[int, float]]]) Coordinates of the available ground-truth boxes
        preds: (List[List[Union[int, float]]]) Coordinates of the predicted boxes,
               sorted by confidence value (descending)
        threshold: (float) Threshold
        form: (str) Format of the coordinates
        ious: (np.ndarray) len(gts) x len(preds) matrix for storing calculated ious.

    Return:
        (float) Precision
    """
    n = len(preds)
    tp = 0
    fp = 0

    for pred_idx in range(n):

        best_match_gt_idx = find_best_match(gts, preds[pred_idx], pred_idx,
                                            threshold=threshold, form=form, ious=ious)

        if best_match_gt_idx >= 0:
            # True positive: The predicted box matches a gt box with an IoU above the threshold.
            tp += 1
            # Remove the matched GT box
            gts[best_match_gt_idx] = -1
        else:
            # No match
            # False positive: indicates a predicted box had no associated gt box.
            fp += 1

    # False negative: indicates a gt box had no associated predicted box.
    fn = (gts.sum(axis=1) > 0).sum()

    return tp / (tp + fp + fn)
In [ ]:
def train(dataloader, lr_scheduler, model, optimizer,
          device, epoch, loss_hist, itr):
    model.train()
    start = time.time()
    loss_hist.reset()
    for images, targets in dataloader:
        images = list(image.to(device) for image in images)
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        loss_dict = model(images, targets)
        losses = sum(loss for loss in loss_dict.values())
        loss_value = losses.item()
        loss_hist.send(loss_value)
        optimizer.zero_grad()
        losses.backward()
        optimizer.step()
        if itr % 100 == 0:
            print(f"Epoch #{epoch} iteration #{itr} loss: {loss_value}")
        itr += 1
    end = time.time()
    return loss_hist, end, start

def validate(dataloader, model, device, iou_thresholds):
    valid_image_precision = []
    model.eval()
    with torch.no_grad():
        for images, targets in dataloader:

            images = list(image.to(device) for image in images)
            targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

            outputs = model(images)
    for i, image in enumerate(images):
        boxes = outputs[i]['boxes'].data.cpu().numpy()
        scores = outputs[i]['scores'].data.cpu().numpy()
        gt_boxes = targets[i]['boxes'].cpu().numpy()
        preds_sorted_idx = np.argsort(scores)[::-1]
        preds_sorted = boxes[preds_sorted_idx]
        image_precision = calculate_image_precision(preds_sorted,
                                                        gt_boxes,
                                                        thresholds=iou_thresholds,
                                                        form='coco')
        valid_image_precision.append(image_precision)

    valid_prec = np.mean(valid_image_precision)
    return valid_prec

Model Training and Validation

Now that the model has been initiated, we will train it. The parameter for setting the number of epochs for training is (num_epochs) and is set to 8. We have optimized the model using the SGD or Stochastic gradient descent method.

To minimize the loss function, we have set parameters as mentioned below -

• lr_scheduler is set to None

• Learning rate (lr) is set to 0.001

• requires_grad is set to True for gradients to be computed in back propagation

• momentum is set to 0.9 and weight_decay is set to 0.0005

If we want to save the trained weights, we can use torch.save to save and use the code underneath it to load it when needed.

For training, model is minimizing loss function.

For validation, our model is using Mean Average Precision and IOU threshold as 0.5

In [ ]:
torch.cuda.is_available()
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
def get_model():
    # load the COCO pre-trained model
    model = torchvision.models.detection.fasterrcnn_resnet50_fpn_v2(weights='DEFAULT')
    # one class is pneumonia, and the other is background
    num_classes = 2
    # get the input features for the classifier
    in_features = model.roi_heads.box_predictor.cls_score.in_features
    # replace pre-trained head with our features head
    # the head layer will classify the images based on our data input features
    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
    return model
In [ ]:
# learning parameters
num_epochs = 8
lr = 0.001
batch_size = 6
train_loss = []
precision = []

# initialize the Averager
loss_hist = Averager()
iou_thresholds = [x for x in np.arange(0.5, 0.76, 0.05)]

model = get_model().to(device)
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=lr, momentum=0.9, weight_decay=0.0005)
lr_scheduler = None

for epoch in range(num_epochs):
    itr = 1
    train_loss_hist, end, start = train(train_data_loader, lr_scheduler,
                                        model, optimizer, device,
                                        epoch, loss_hist, itr)
    valid_prec = validate(valid_data_loader, model, device, iou_thresholds)
    print(f"Took {(end-start)/60:.3f} minutes for epoch# {epoch} to train")
    print(f"Epoch #{epoch} Train loss: {train_loss_hist.value}")
    print(f"Epoch #{epoch} Validation Precision: {valid_prec}")
    train_loss.append(train_loss_hist.value)
    precision.append(valid_prec)

    # update the learning rate
    if lr_scheduler is not None:
        lr_scheduler.step()

torch.save(model.state_dict(), 'fasterrcnn_resnet50_fpn_pneumonia_detection.pth')
Downloading: "https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_v2_coco-dd69338a.pth" to /root/.cache/torch/hub/checkpoints/fasterrcnn_resnet50_fpn_v2_coco-dd69338a.pth

100%|██████████| 167M/167M [00:01<00:00, 169MB/s]  
Epoch #0 iteration #100 loss: 0.36503443121910095

Epoch #0 iteration #200 loss: 0.3593102693557739

Epoch #0 iteration #300 loss: 0.2480885237455368

Epoch #0 iteration #400 loss: 0.2986085116863251

Epoch #0 iteration #500 loss: 0.3035193085670471

Epoch #0 iteration #600 loss: 0.28615203499794006

Epoch #0 iteration #700 loss: 0.3310244083404541

Took 13.236 minutes for epoch# 0 to train

Epoch #0 Train loss: 0.31745783341865913

Epoch #0 Validation Precision: 0.16418650793650794

Epoch #1 iteration #100 loss: 0.3212285339832306

Epoch #1 iteration #200 loss: 0.2446032613515854

Epoch #1 iteration #300 loss: 0.2512800991535187

Epoch #1 iteration #400 loss: 0.2469700276851654

Epoch #1 iteration #500 loss: 0.280222088098526

Epoch #1 iteration #600 loss: 0.2569520175457001

Epoch #1 iteration #700 loss: 0.28918418288230896

Took 13.172 minutes for epoch# 1 to train

Epoch #1 Train loss: 0.2907198983706346

Epoch #1 Validation Precision: 0.18124236874236874

Epoch #2 iteration #100 loss: 0.3107304573059082

Epoch #2 iteration #200 loss: 0.25228461623191833

Epoch #2 iteration #300 loss: 0.23900437355041504

Epoch #2 iteration #400 loss: 0.2612660527229309

Epoch #2 iteration #500 loss: 0.25382906198501587

Epoch #2 iteration #600 loss: 0.29772183299064636

Epoch #2 iteration #700 loss: 0.2840990126132965

Took 13.180 minutes for epoch# 2 to train

Epoch #2 Train loss: 0.2849202402123884

Epoch #2 Validation Precision: 0.21574675324675324

Epoch #3 iteration #100 loss: 0.28597262501716614

Epoch #3 iteration #200 loss: 0.22964544594287872

Epoch #3 iteration #300 loss: 0.2503037750720978

Epoch #3 iteration #400 loss: 0.22822438180446625

Epoch #3 iteration #500 loss: 0.25228601694107056

Epoch #3 iteration #600 loss: 0.2728104293346405

Epoch #3 iteration #700 loss: 0.27873876690864563

Took 13.213 minutes for epoch# 3 to train

Epoch #3 Train loss: 0.28231633007943796

Epoch #3 Validation Precision: 0.20642436267436268

Epoch #4 iteration #100 loss: 0.3009676933288574

Epoch #4 iteration #200 loss: 0.24012809991836548

Epoch #4 iteration #300 loss: 0.2406945377588272

Epoch #4 iteration #400 loss: 0.23617839813232422

Epoch #4 iteration #500 loss: 0.25078845024108887

Epoch #4 iteration #600 loss: 0.2682115435600281

Epoch #4 iteration #700 loss: 0.28912079334259033

Took 13.188 minutes for epoch# 4 to train

Epoch #4 Train loss: 0.2805629870971712

Epoch #4 Validation Precision: 0.175

Epoch #5 iteration #100 loss: 0.29064399003982544

Epoch #5 iteration #200 loss: 0.21240606904029846

Epoch #5 iteration #300 loss: 0.2539086639881134

Epoch #5 iteration #400 loss: 0.2431095540523529

Epoch #5 iteration #500 loss: 0.2606295943260193

Epoch #5 iteration #600 loss: 0.2684011459350586

Epoch #5 iteration #700 loss: 0.26061707735061646

Took 13.179 minutes for epoch# 5 to train

Epoch #5 Train loss: 0.2790281881763488

Epoch #5 Validation Precision: 0.21448412698412697

Epoch #6 iteration #100 loss: 0.27606046199798584

Epoch #6 iteration #200 loss: 0.21379034221172333

Epoch #6 iteration #300 loss: 0.23880916833877563

Epoch #6 iteration #400 loss: 0.22491750121116638

Epoch #6 iteration #500 loss: 0.2669491469860077

Epoch #6 iteration #600 loss: 0.2712382376194

Epoch #6 iteration #700 loss: 0.2895532548427582

Took 13.181 minutes for epoch# 6 to train

Epoch #6 Train loss: 0.27705336036551903

Epoch #6 Validation Precision: 0.251984126984127

Epoch #7 iteration #100 loss: 0.2856082022190094

Epoch #7 iteration #200 loss: 0.24783116579055786

Epoch #7 iteration #300 loss: 0.22515460848808289

Epoch #7 iteration #400 loss: 0.2147449254989624

Epoch #7 iteration #500 loss: 0.22745268046855927

Epoch #7 iteration #600 loss: 0.26497119665145874

Epoch #7 iteration #700 loss: 0.3005732595920563

Took 13.195 minutes for epoch# 7 to train

Epoch #7 Train loss: 0.2743941983964597

Epoch #7 Validation Precision: 0.20499338624338623

Model Performance Evaluation

In our test dataset, we have 3000 images. We predicted bounding boxes and scores for the test images. Detection Threshold used is 0.8.

• Test images are obtained from the image path

• Each image is converted to image tensor using PyTorch’s Transforms

• The image is passed through the model to get the predictions

• Scores and box coordinates are obtained, but only prediction score > threshold is chosen.

Predicted result has XX images with one or more bounding boxes.

In [ ]:
# plot the training loss
plt.figure()
plt.plot(train_loss, label='Training loss')
plt.legend()
plt.show()

# plot the validation precision
plt.figure()
plt.plot(precision, label='Validation precision')
plt.legend()
plt.show()

We load the saved dictionary state.

  • Displaying count of Test image instances
  • Also, displaying the network architecture
In [ ]:
images_test_path = '/kaggle/input/pneumonia-dataset/stage_2_test_images/stage_2_test_images/'
test_images = os.listdir(images_test_path)
print(f"Validation instances: {len(test_images)}")

# # load a model; pre-trained on COCO
model = get_model()

# # os.makedirs('../validation_predictions', exist_ok=True)
model.load_state_dict(torch.load('fasterrcnn_resnet50_fpn_pneumonia_detection.pth'))
model.to(device)
Validation instances: 3000
Out[ ]:
FasterRCNN(
  (transform): GeneralizedRCNNTransform(
      Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
      Resize(min_size=(800,), max_size=1333, mode='bilinear')
  )
  (backbone): BackboneWithFPN(
    (body): IntermediateLayerGetter(
      (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace=True)
      (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
      (layer1): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
      )
      (layer2): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
      )
      (layer3): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (4): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (5): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
      )
      (layer4): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu): ReLU(inplace=True)
        )
      )
    )
    (fpn): FeaturePyramidNetwork(
      (inner_blocks): ModuleList(
        (0): Conv2dNormActivation(
          (0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
        (1): Conv2dNormActivation(
          (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
        (2): Conv2dNormActivation(
          (0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
        (3): Conv2dNormActivation(
          (0): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (layer_blocks): ModuleList(
        (0-3): 4 x Conv2dNormActivation(
          (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (extra_blocks): LastLevelMaxPool()
    )
  )
  (rpn): RegionProposalNetwork(
    (anchor_generator): AnchorGenerator()
    (head): RPNHead(
      (conv): Sequential(
        (0): Conv2dNormActivation(
          (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (1): ReLU(inplace=True)
        )
        (1): Conv2dNormActivation(
          (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (1): ReLU(inplace=True)
        )
      )
      (cls_logits): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
      (bbox_pred): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
    )
  )
  (roi_heads): RoIHeads(
    (box_roi_pool): MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'], output_size=(7, 7), sampling_ratio=2)
    (box_head): FastRCNNConvFCHead(
      (0): Conv2dNormActivation(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU(inplace=True)
      )
      (1): Conv2dNormActivation(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU(inplace=True)
      )
      (2): Conv2dNormActivation(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU(inplace=True)
      )
      (3): Conv2dNormActivation(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU(inplace=True)
      )
      (4): Flatten(start_dim=1, end_dim=-1)
      (5): Linear(in_features=12544, out_features=1024, bias=True)
      (6): ReLU(inplace=True)
    )
    (box_predictor): FastRCNNPredictor(
      (cls_score): Linear(in_features=1024, out_features=2, bias=True)
      (bbox_pred): Linear(in_features=1024, out_features=8, bias=True)
    )
  )
)

For each image in the test dataset, we evaluate the model to obtain:

  • boxes: a list of bounding boxes.
  • labels: a label assigned to each bounding box.
  • scores: a probability for each label .
In [ ]:
def format_prediction_string(boxes, scores):
    pred_strings = []
    for j in zip(scores, boxes):
        pred_strings.append("{0:.4f} {1} {2} {3} {4}".format(j[0],
                                                             int(j[1][0]), int(j[1][1]),
                                                             int(j[1][2]), int(j[1][3])))

    return " ".join(pred_strings)

Displaying sample images with predicted bounding box

In [ ]:
 detection_threshold = 0.8
 results = []
 model.eval()
 f, axarr = plt.subplots(10, 3, figsize=(24,36))
 axarr = axarr.ravel()
 axidx = 0
 with torch.no_grad():
    for i, image in tqdm(enumerate(test_images), total=len(test_images)):

         # plot image
         ID = "ID: ",format(image)
         #orig_image = cv2.imread(f"{images_test_path}/{test_images[i]}", cv2.IMREAD_COLOR)
         orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
         image = orig_image.pixel_array
         image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
         image /= 255.0
         image = np.transpose(image, (2, 0, 1)).astype(np.float32)
         image = torch.tensor(image, dtype=torch.float).cuda()
         image = torch.unsqueeze(image, 0)

         model.eval()
         cpu_device = torch.device("cpu")

         outputs = model(image)

         outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
         if len(outputs[0]['boxes']) != 0:
             for counter in range(len(outputs[0]['boxes'])):
                 boxes = outputs[0]['boxes'].data.cpu().numpy()
                 scores = outputs[0]['scores'].data.cpu().numpy()
                 boxes = boxes[scores >= detection_threshold].astype(np.int32)
                 draw_boxes = boxes.copy()
                 boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
                 boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
                 #print(image.shape)
                 #print(boxes)
                 draw_boxes = boxes.copy()
                 axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
                 axarr[axidx].set_title(ID)

                 for box in draw_boxes:
                    rectangle = Rectangle(xy= ((int(box[0]), int(box[1]))),width=int(box[2]),
                                          height=int(box[3]), color="red",alpha = 0.1)
                    axarr[axidx].add_patch(rectangle)

             axidx+=1
             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': format_prediction_string(boxes, scores)
            }
             results.append(result)
         else:
             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': None
            }
             results.append(result)
         i=i+1
         #exit after 32 images
         if i>29:
             break
 #sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
 #print(sub_df.head())
 #sub_df.to_csv('submission.csv', index=False)
  1%|          | 29/3000 [00:04<07:53,  6.27it/s]
In [ ]:
 detection_threshold = 0.8
 results = []
 model.eval()
 with torch.no_grad():
    for i, image in tqdm(enumerate(test_images), total=len(test_images)):

         # plot image
         orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
         image = orig_image.pixel_array

         image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
         image /= 255.0
         image = np.transpose(image, (2, 0, 1)).astype(np.float32)
         image = torch.tensor(image, dtype=torch.float).cuda()
         image = torch.unsqueeze(image, 0)

         model.eval()
         cpu_device = torch.device("cpu")

         outputs = model(image)

         outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
         if len(outputs[0]['boxes']) != 0:
             for counter in range(len(outputs[0]['boxes'])):
                 boxes = outputs[0]['boxes'].data.cpu().numpy()
                 scores = outputs[0]['scores'].data.cpu().numpy()
                 boxes = boxes[scores >= detection_threshold].astype(np.int32)
                 draw_boxes = boxes.copy()
                 boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
                 boxes[:, 3] = boxes[:, 3] - boxes[:, 1]

                 draw_boxes = boxes.copy()

             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': format_prediction_string(boxes, scores)
            }
             results.append(result)
         else:
             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': ''
            }
             results.append(result)

 sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
 print(sub_df.head())
 sub_df.to_csv('submission_frcnn.csv', index=False)
100%|██████████| 3000/3000 [06:00<00:00,  8.33it/s]
                              patientId  \

0  12abc170-f1fe-45d3-b574-2f4d030e40cd   

1  2abcf934-facd-40fc-a75e-0062441fd206   

2  2da69f80-c59d-4e4a-b7e5-1d631ef4186b   

3  13e4e6e6-faa2-4bbc-8e1e-610623de994e   

4  2afe02a3-06da-42fa-b68f-3e9c921e5fb9   



                                PredictionString  

0                                                 

1  0.9593 561 275 173 436 0.9328 197 298 181 341  

2                         0.8360 235 456 146 139  

3                                                 

4                                                 

Output:

  • Test images are obtained from the image path and converted to image tensor using PyTorch’s Transforms.
  • Each image is passed through the model to get the predictions.
  • Class, box coordinates are obtained, but only when score is greater than detection threshold value of 0.8.
In [ ]:
sub_df
Out[ ]:
patientId PredictionString
0 12abc170-f1fe-45d3-b574-2f4d030e40cd
1 2abcf934-facd-40fc-a75e-0062441fd206 0.9593 561 275 173 436 0.9328 197 298 181 341
2 2da69f80-c59d-4e4a-b7e5-1d631ef4186b 0.8360 235 456 146 139
3 13e4e6e6-faa2-4bbc-8e1e-610623de994e
4 2afe02a3-06da-42fa-b68f-3e9c921e5fb9
... ... ...
2995 1ef2bfbf-b68d-4981-8dc3-b5d7b54ad55e
2996 1fc3831a-7b78-48c5-90c1-af8971ee9eae
2997 20da1944-1714-4170-a08a-8b82c0788ad5 0.8825 200 502 197 113
2998 13c6a303-2c21-4edf-9dca-4999dafe8a4e
2999 2b83d54b-af50-4c15-9d53-d3b1c5381678

3000 rows × 2 columns

Prediction of bounding boxes with Confidence Score for the test images. Out of total of 3000 images, 1098 images have been detected as Pneumonia cases with one or more bounding boxes.

In [ ]:
sub_df[sub_df['PredictionString']!='']
Out[ ]:
patientId PredictionString
1 2abcf934-facd-40fc-a75e-0062441fd206 0.9593 561 275 173 436 0.9328 197 298 181 341
2 2da69f80-c59d-4e4a-b7e5-1d631ef4186b 0.8360 235 456 146 139
6 2a7df7aa-1314-40da-afc5-7af58ad1bee9 0.9230 142 344 211 421
8 0de33fbf-998c-4c91-9561-df7343873bc2 0.9313 646 533 184 193
9 1eeecd10-16a2-476f-8d81-867d5480bf01 0.9270 256 481 176 151 0.8682 637 438 173 228
... ... ...
2985 140ebc5d-5a15-4948-b698-0a4b32d12a93 0.8276 144 359 228 491
2989 26586d01-b992-41c4-a7a4-c9f1f8d102ad 0.9242 192 396 212 336 0.8151 625 434 189 383
2990 23ebfb85-2312-4a8b-8879-3cf48a1e8920 0.9041 646 367 200 382
2991 2dbac7d7-9100-4861-8e15-fa2adf82c6e3 0.8707 758 264 217 432 0.8068 285 252 240 408
2997 20da1944-1714-4170-a08a-8b82c0788ad5 0.8825 200 502 197 113

1098 rows × 2 columns

Function to show an image with predicted bounding box coordinates

In [ ]:
validation_threshold=0.8
def show_pred_image_with_bboxes(patientId,axarr,axidx):
    with torch.no_grad():
        ID = "Predicted: ",format(patientId)

        orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
        image = orig_image.pixel_array

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
        image /= 255.0
        image = np.transpose(image, (2, 0, 1)).astype(np.float32)
        image = torch.tensor(image, dtype=torch.float).cuda()
        image = torch.unsqueeze(image, 0)

        model.eval()
        cpu_device = torch.device("cpu")

        outputs = model(image)

        outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
        if len(outputs[0]['boxes']) != 0:
            for counter in range(len(outputs[0]['boxes'])):
                boxes = outputs[0]['boxes'].data.cpu().numpy()
                scores = outputs[0]['scores'].data.cpu().numpy()
                boxes = boxes[scores >= validation_threshold].astype(np.int32)
                draw_boxes = boxes.copy()
                boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
                boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
                draw_boxes = boxes.copy()
                axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
                axarr[axidx].set_title(ID)

                for box in draw_boxes:
                    rectangle = Rectangle(xy= ((int(box[0]), int(box[1]))),width=int(box[2]),
                                          height=int(box[3]), color="red",alpha = 0.1)
                    axarr[axidx].add_patch(rectangle)

Function to show an image with actual bounding box coordinates

In [ ]:
def show_image_with_bboxes(patientId,axarr,axidx):
        ID = "Actual: ",format(patientId)
        id_= np.random.choice(train_labels_df_pos['patientId'].values)
        orig_image = pydicom.read_file(os.path.join(IMAGE_PATH + '%s.dcm' % patientId))
        image = orig_image.pixel_array
        axarr[axidx].imshow(cv2.cvtColor(orig_image.pixel_array, cv2.COLOR_BGR2RGB))
        axarr[axidx].set_title(ID)
        boxes=train_labels_df_pos[['x','y','width','height']][train_labels_df_pos['patientId']==id_].values
        for box in boxes:
            x=box[0]
            y=box[1]
            w=box[2]
            h=box[3]
            axarr[axidx].add_patch(plt.Rectangle((x, y), w, h, color='red', fill=False, linewidth=3))

For Demonstration purposes, displaying sample images with actual and predicted bounding box.

In [ ]:
#1352a7f3-1f0d-4f1f-af05-daa5d7f8624a
dataset = valid_df
f, axarr = plt.subplots(6, 2, figsize=(16,36))
axarr = axarr.ravel()
axidx = 0

image_id = valid_df.sample(6)['patientId'].reset_index(drop=True)
for i in range(6):

    show_image_with_bboxes(image_id[i],axarr,axidx)
    axidx+=1
    show_pred_image_with_bboxes(image_id[i],axarr,axidx)
    axidx+=1

Observation

With the backbone architecture as Resnet 50 VPN2, we are able to train/fit our data and provide results generating the bounding box coordinates of possibly infected chest area with high objectness scores of > 0.8 threshold. Training Loss is around 0.27 with 8 EPOCHS. This needs to be tried with more number of EPOCHS for better training and results. Out of 3000 test samples, 1098 samples have been detected as positive cases having one or more bounding boxes. The same results have been updated in the submission file.

Limitation of Faster R-CNN

1) Data requirements

One of the main challenges of applying Faster R-CNN to real-world scenarios is the data requirements. These models need large amounts of annotated data to train and fine-tune, which can be costly, time-consuming, and prone to errors. Moreover, the data needs to be representative of the target domain and scenario, which may not always be available or easy to obtain. To overcome this challenge, some possible solutions are to use data augmentation, transfer learning, synthetic data, or weakly supervised learning.

2) Computational complexity

Another challenge of applying Faster R-CNN to real-world scenarios is the computational complexity. These models have many layers and parameters, which require high-end hardware and resources to train and run. Moreover, these models can be slow to process images, especially when dealing with high-resolution or multiple objects. This can limit their applicability and scalability in scenarios that require real-time or low-latency performance. To overcome this challenge, some possible solutions are to use model compression, pruning, quantization, or hardware acceleration.

3) Generalization and robustness

A third challenge of applying Faster R-CNN to real-world scenarios is the generalization and robustness. These models can perform well on standard benchmarks and datasets, but they may not be able to handle variations and uncertainties in the real world. For example, these models may struggle with occlusions, distortions, illumination changes, background clutter, or adversarial attacks. These factors can affect the accuracy and reliability of the models, and potentially cause failures or harm. To overcome this challenge, some possible solutions are to use data diversity, regularization, adversarial training, or self-supervised learning.

4) Interpretability and explainability

A fourth challenge of applying Faster R-CNN to real-world scenarios is the interpretability and explainability. These models are often considered as black boxes, meaning that it is hard to understand how they make decisions and what features they use. This can pose problems for trust, accountability, and ethics, especially in scenarios that involve high-stakes or sensitive applications. For example, these models may produce false positives, false negatives, or biased results, which can have serious consequences or implications. To overcome this challenge, some possible solutions are to use visualization, attribution, or causal inference techniques.

5) Ethical and social issues

A fifth challenge of applying Faster R-CNN to real-world scenarios is ethical and social issues. These models can enable many beneficial and innovative applications, but they can also raise concerns and risks for privacy, security, human rights, and social justice. For example, these models may be used for surveillance, profiling, discrimination, or manipulation, which can violate the rights and interests of individuals or groups. To overcome this challenge, some possible solutions are to use privacy-preserving, secure, or fair methods, or to follow ethical guidelines and principles.

3. Object Detection using Yolo¶

‘Object Detection’ deals with localizing a region of interest within an image and classifying this region like a typical image classifier. One image can include several regions of interest pointing to different objects. This makes object detection a more advanced problem of image classification.

YOLO (You Only Look Once) is a popular object detection model known for its speed and accuracy. It was first introduced by Joseph Redmon et al. in 2016 and has since undergone several iterations, the latest being YOLO v7. It is a single-shot detector that uses a fully convolutional neural network (CNN) to process an image.

YOLO proposes using an end-to-end neural network that makes predictions of bounding boxes and class probabilities all at once. It differs from the approach taken by previous object detection algorithms, which repurposed classifiers to perform detection. Following a fundamentally different approach to object detection, YOLO achieved state-of-the-art results, beating other real-time object detection algorithms by a large margin. The YOLO algorithm takes an image as input and then uses a simple deep convolutional neural network to detect objects in the image.

For this Capstone Project, we did try YOLO v3. It was introduced in 2018 as an improvement over YOLO v2, aiming to increase the accuracy and speed of the algorithm.

Improvements in YOLO v3:

  1. It uses new CNN architecture called Darknet-53. Darknet-53 is a variant of the ResNet architecture and is designed specifically for object detection tasks. It has 53 convolutional layers and is able to achieve state-of-the-art results on various object detection benchmarks.
  2. Here the anchor boxes are with different scales and aspect ratios. In YOLO v2, the anchor boxes were all the same size, which limited the ability of the algorithm to detect objects of different sizes and shapes. In YOLO v3 the anchor boxes are scaled, and aspect ratios are varied to better match the size and shape of the objects being detected
  3. YOLO v3 also introduces the concept of "feature pyramid networks" (FPN). FPNs are a CNN architecture used to detect objects at multiple scales. They construct a pyramid of feature maps, with each level of the pyramid being used to detect objects at a different scale. This helps to improve the detection performance on small objects, as the model is able to see the objects at multiple scales.
  4. YOLO v3 can handle a wider range of object sizes and aspect ratios. It is also more accurate and stable than the previous versions of YOLO.

Introduction YOLOv3 paper

In [ ]:
import math
import os
import shutil
import sys

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import glob
import pydicom
import cv2
from sklearn.model_selection import train_test_split
from tqdm import tqdm
from darknet import *
In [ ]:
random_stat = 123
np.random.seed(random_stat)

Clone and Build YOLOv3

In [ ]:
!git clone https://github.com/pjreddie/darknet.git
Cloning into 'darknet'...
remote: Enumerating objects: 5955, done.
remote: Total 5955 (delta 0), reused 0 (delta 0), pack-reused 5955
Receiving objects: 100% (5955/5955), 6.37 MiB | 15.32 MiB/s, done.
Resolving deltas: 100% (3931/3931), done.
In [ ]:
!cd darknet && make -j 999 -s
In [ ]:
!cp darknet/darknet darknet_gpu

Data Migration for YOLOv3

Make subdirectories

In [ ]:
DATA_DIR = "/kaggle/input/pneumonia-dataset"

train_dcm_dir = os.path.join(DATA_DIR, "stage_2_train_images/stage_2_train_images")
test_dcm_dir = os.path.join(DATA_DIR, "stage_2_test_images/stage_2_test_images")

img_dir = os.path.join(os.getcwd(), "images")  # .jpg
label_dir = os.path.join(os.getcwd(), "labels")  # .txt
metadata_dir = os.path.join(os.getcwd(), "metadata") # .txt

# YOLOv3 config file directory
cfg_dir = os.path.join(os.getcwd(), "cfg")
# YOLOv3 training checkpoints will be saved here
backup_dir = os.path.join(os.getcwd(), "backup")

for directory in [img_dir, label_dir, metadata_dir, cfg_dir, backup_dir]:
    if os.path.isdir(directory):
        continue
    os.mkdir(directory)
In [ ]:
!ls -shtl
total 740K
4.0K drwxr-xr-x  2 root root 4.0K Sep  9 11:59 backup
4.0K drwxr-xr-x  2 root root 4.0K Sep  9 11:59 cfg
4.0K drwxr-xr-x  2 root root 4.0K Sep  9 11:59 metadata
4.0K drwxr-xr-x  2 root root 4.0K Sep  9 11:59 labels
4.0K drwxr-xr-x  2 root root 4.0K Sep  9 11:59 images
716K -rwxr-xr-x  1 root root 716K Sep  9 11:59 darknet_gpu
4.0K drwxr-xr-x 13 root root 4.0K Sep  9 11:55 darknet

Load stage_2_train_labels.csv

In [ ]:
annots = pd.read_csv(os.path.join(DATA_DIR, "stage_2_train_labels.csv"))
annots.head()
Out[ ]:
patientId x y width height Target
0 0004cfab-14fd-4e49-80ba-63a80b6bddd6 NaN NaN NaN NaN 0
1 00313ee0-9eaa-42f4-b0ab-c148ed3241cd NaN NaN NaN NaN 0
2 00322d4d-1c29-4943-afc9-b6754be640eb NaN NaN NaN NaN 0
3 003d8fa0-6bf1-40ed-b54c-ac657f8495c5 NaN NaN NaN NaN 0
4 00436515-870c-4b36-a041-de91049b9ab4 264.0 152.0 213.0 379.0 1

Generate images and labels for training YOLOv3

  • YOLOv3 needs .txt file for each image, that contains bounding box details like:
    <object-class> <x1> <y1> <w1> <h1>
    <object-class> <x2> <y2> <w2> <h2>

object-class: Since RSNA task is binary classification basically, is 0.

x,y: Float values of bounding box center coordinate, divided by image width and height respectively.

w,h: Width and Height of boounding box, divided by image width and height respectively.

So it is different from the format of label data provided. Hence changing it below should change it.

In [ ]:
def save_img_from_dcm_yolo(dcm_dir, img_dir, patient_id):
    img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
    if os.path.exists(img_fp):
        return
    dcm_fp = os.path.join(dcm_dir, "{}.dcm".format(patient_id))
    img_1ch = pydicom.read_file(dcm_fp).pixel_array
    img_3ch = np.stack([img_1ch]*3, -1)

    img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
    cv2.imwrite(img_fp, img_3ch)

def save_label_from_dcm_yolo(label_dir, patient_id, row=None):
    # rsna defualt image size
    img_size = 1024
    label_fp = os.path.join(label_dir, "{}.txt".format(patient_id))

    f = open(label_fp, "a")
    if row is None:
        f.close()
        return

    top_left_x = row[1]
    top_left_y = row[2]
    w = row[3]
    h = row[4]

    # 'r' means relative. 'c' means center.
    rx = top_left_x/img_size
    ry = top_left_y/img_size
    rw = w/img_size
    rh = h/img_size
    rcx = rx+rw/2
    rcy = ry+rh/2

    line = "{} {} {} {} {}\n".format(0, rcx, rcy, rw, rh)

    f.write(line)
    f.close()

def save_yolov3_data_from_rsna(dcm_dir, img_dir, label_dir, annots):
    for row in tqdm(annots.values):
        patient_id = row[0]

        img_fp = os.path.join(img_dir, "{}.jpg".format(patient_id))
        if os.path.exists(img_fp):
            save_label_from_dcm_yolo(label_dir, patient_id, row)
            continue
        target = row[5]
        # In order to save space, limiting to files with bounding box
        if target == 0:
            continue
        save_label_from_dcm_yolo(label_dir, patient_id, row)
        save_img_from_dcm_yolo(dcm_dir, img_dir, patient_id)
In [ ]:
save_yolov3_data_from_rsna(train_dcm_dir, img_dir, label_dir, annots)
100%|██████████| 30227/30227 [04:18<00:00, 117.03it/s]
In [ ]:
!du -sh images labels
990M	images
24M	labels

Plot a sample train image and label

In [ ]:
ex_patient_id = annots[annots.Target == 1].patientId.values[0]
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))
ex_label_path = os.path.join(label_dir, "{}.txt".format(ex_patient_id))

plt.imshow(cv2.imread(ex_img_path))

img_size = 1014
with open(ex_label_path, "r") as f:
    for line in f:
        print(line)
        class_id, rcx, rcy, rw, rh = list(map(float, line.strip().split()))
        x = (rcx-rw/2)*img_size
        y = (rcy-rh/2)*img_size
        w = rw*img_size
        h = rh*img_size
        plt.plot([x, x, x+w, x+w, x], [y, y+h, y+h, y, y])
0 0.36181640625 0.33349609375 0.2080078125 0.3701171875

0 0.673828125 0.36962890625 0.25 0.4423828125

Generate train/val file path list (.txt)

Giving the list of image paths to YOLO. two seperate list textfiles for training images and validation images.

In [ ]:
def write_train_list_yolo(metadata_dir, img_dir, name, series):
    list_fp = os.path.join(metadata_dir, name)
    with open(list_fp, "w") as f:
        for patient_id in series:
            line = "{}\n".format(os.path.join(img_dir, "{}.jpg".format(patient_id)))
            f.write(line)
In [ ]:
# Lines without any bounding box is removed
patient_id_series = annots[annots.Target == 1].patientId.drop_duplicates()

tr_series, val_series = train_test_split(patient_id_series, test_size=0.1, random_state=random_stat)
print("The # of train set: {}, The # of validation set: {}".format(tr_series.shape[0], val_series.shape[0]))

# train image path list
write_train_list_yolo(metadata_dir, img_dir, "tr_list.txt", tr_series)
# validation image path list
write_train_list_yolo(metadata_dir, img_dir, "val_list.txt", val_series)
The # of train set: 5410, The # of validation set: 602

Create test image and labels for YOLOv3

In [ ]:
def save_yolov3_test_data(test_dcm_dir, img_dir, metadata_dir, name, series):
    list_fp = os.path.join(metadata_dir, name)
    with open(list_fp, "w") as f:
        for patient_id in series:
            save_img_from_dcm_yolo(test_dcm_dir, img_dir, patient_id)
            line = "{}\n".format(os.path.join(img_dir, "{}.jpg".format(patient_id)))
            f.write(line)
In [ ]:
test_dcm_fps = list(set(glob.glob(os.path.join(test_dcm_dir, '*.dcm'))))
test_dcm_fps = pd.Series(test_dcm_fps).apply(lambda dcm_fp: dcm_fp.strip().split("/")[-1].replace(".dcm",""))

save_yolov3_test_data(test_dcm_dir, img_dir, metadata_dir, "te_list.txt", test_dcm_fps)

Plot a sample test Image

In [ ]:
ex_patient_id = test_dcm_fps[0]
print(ex_patient_id)
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))
plt.imshow(cv2.imread(ex_img_path))
1e3bf52d-b83e-4503-9b70-829b52d82269
Out[ ]:
<matplotlib.image.AxesImage at 0x794476917190>
In [ ]:
ex_patient_id='76f71a93-8105-4c79-a010-0cfa86f0061a' #Picked the same image used in Milestone 1 (Patient having pneumonia with 4 bounding box)
ex_img_path = os.path.join(img_dir, "{}.jpg".format(ex_patient_id))

plt.imshow(cv2.imread(ex_img_path))
Out[ ]:
<matplotlib.image.AxesImage at 0x79447771d600>

Prepare Configuration Files for Using YOLOv3 pre-trained weights and config files are required for Yolo. cfg/rsna.data, cfg/rsna.names, darknet53.conv.74,cfg/rsna_yolov3.cfg_train cfg/rsna.data file point to RSNA data path

  • train: Path to training image list textfile
  • val: Path to validation image list textfile
  • names: RSNA class name list (see 3.1)
  • backup: A directory where trained weights(checkpoints) will be stored as training progresses.
In [ ]:
data_extention_file_path = os.path.join(cfg_dir, 'rsna.data')
with open(data_extention_file_path, 'w') as f:
    contents = """classes= 1
train  = {}
valid  = {}
names  = {}
backup = {}
    """.format(os.path.join(metadata_dir, "tr_list.txt"),
               os.path.join(metadata_dir, "val_list.txt"),
               os.path.join(cfg_dir, 'rsna.names'),
               backup_dir)
    f.write(contents)
In [ ]:
!cat cfg/rsna.data
classes= 1
train  = /kaggle/working/metadata/tr_list.txt
valid  = /kaggle/working/metadata/val_list.txt
names  = /kaggle/working/cfg/rsna.names
backup = /kaggle/working/backup
    

- cfg/rsna.names¶

In [ ]:
# Label list of bounding box.
!echo "pneumonia" > cfg/rsna.names

- darknet53.conv.74 (Download Pre-trained Model)¶

For training, downloading pre-trained model weights(darknet53.conv.74) using wget command. Downloaded cfg file that was already edited for RSNA.

In [ ]:
!wget -q https://pjreddie.com/media/files/darknet53.conv.74
In [ ]:
!wget --no-check-certificate -q "https://docs.google.com/uc?export=download&id=18ptTK4Vbeokqpux8Onr0OmwUP9ipmcYO" -O cfg/rsna_yolov3.cfg_train

Training YOLOv3

Copy sample test image

In [ ]:
ex_patient_id = annots[annots.Target == 1].patientId.values[2]
shutil.copy(ex_img_path, "test.jpg")
print(ex_patient_id)
00704310-78a8-4b38-8475-49f4573b2dbb
In [ ]:
!wget --load-cookies /tmp/cookies.txt -q "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1FDzMN-kGVYCvBeDKwemAazldSVkAEFyd' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1FDzMN-kGVYCvBeDKwemAazldSVkAEFyd" -O backup/rsna_yolov3_15300.weights && rm -rf /tmp/cookies.txt
In [ ]:
!ls -alsth backup
total 235M
4.0K drwxr-xr-x 2 root root 4.0K Sep  9 12:15 .
4.0K drwxr-xr-x 9 root root 4.0K Sep  9 12:14 ..
235M -rw-r--r-- 1 root root 235M Sep 23  2018 rsna_yolov3_15300.weights

configuration file for test (not for training)

In [ ]:
!wget --no-check-certificate -q "https://docs.google.com/uc?export=download&id=10Yk6ZMAKGz5LeBbikciALy82aK3lX-57" -O cfg/rsna_yolov3.cfg_test
In [ ]:
!cd darknet && ./darknet detector test ../cfg/rsna.data ../cfg/rsna_yolov3.cfg_test ../backup/rsna_yolov3_15300.weights ../test.jpg -thresh 0.005
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 conv     64  3 x 3 / 2   608 x 608 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    2 conv     32  1 x 1 / 1   304 x 304 x  64   ->   304 x 304 x  32  0.379 BFLOPs
    3 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    4 res    1                 304 x 304 x  64   ->   304 x 304 x  64
    5 conv    128  3 x 3 / 2   304 x 304 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    6 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
    7 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    8 res    5                 152 x 152 x 128   ->   152 x 152 x 128
    9 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
   10 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
   11 res    8                 152 x 152 x 128   ->   152 x 152 x 128
   12 conv    256  3 x 3 / 2   152 x 152 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   13 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   14 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   15 res   12                  76 x  76 x 256   ->    76 x  76 x 256
   16 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   17 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   18 res   15                  76 x  76 x 256   ->    76 x  76 x 256
   19 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   20 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   21 res   18                  76 x  76 x 256   ->    76 x  76 x 256
   22 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   23 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   24 res   21                  76 x  76 x 256   ->    76 x  76 x 256
   25 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   26 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   27 res   24                  76 x  76 x 256   ->    76 x  76 x 256
   28 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   29 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   30 res   27                  76 x  76 x 256   ->    76 x  76 x 256
   31 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   32 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   33 res   30                  76 x  76 x 256   ->    76 x  76 x 256
   34 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   35 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   36 res   33                  76 x  76 x 256   ->    76 x  76 x 256
   37 conv    512  3 x 3 / 2    76 x  76 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   38 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   39 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   40 res   37                  38 x  38 x 512   ->    38 x  38 x 512
   41 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   42 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   43 res   40                  38 x  38 x 512   ->    38 x  38 x 512
   44 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   45 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   46 res   43                  38 x  38 x 512   ->    38 x  38 x 512
   47 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   48 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   49 res   46                  38 x  38 x 512   ->    38 x  38 x 512
   50 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   51 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   52 res   49                  38 x  38 x 512   ->    38 x  38 x 512
   53 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   54 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   55 res   52                  38 x  38 x 512   ->    38 x  38 x 512
   56 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   57 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   58 res   55                  38 x  38 x 512   ->    38 x  38 x 512
   59 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   60 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   61 res   58                  38 x  38 x 512   ->    38 x  38 x 512
   62 conv   1024  3 x 3 / 2    38 x  38 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   63 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   64 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   65 res   62                  19 x  19 x1024   ->    19 x  19 x1024
   66 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   67 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   68 res   65                  19 x  19 x1024   ->    19 x  19 x1024
   69 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   70 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   71 res   68                  19 x  19 x1024   ->    19 x  19 x1024
   72 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   73 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   74 res   71                  19 x  19 x1024   ->    19 x  19 x1024
   75 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   76 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   77 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   78 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   79 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   80 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   81 conv     18  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x  18  0.013 BFLOPs
   82 yolo
   83 route  79
   84 conv    256  1 x 1 / 1    19 x  19 x 512   ->    19 x  19 x 256  0.095 BFLOPs
   85 upsample            2x    19 x  19 x 256   ->    38 x  38 x 256
   86 route  85 61
   87 conv    256  1 x 1 / 1    38 x  38 x 768   ->    38 x  38 x 256  0.568 BFLOPs
   88 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   89 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   90 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   91 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   92 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   93 conv     18  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x  18  0.027 BFLOPs
   94 yolo
   95 route  91
   96 conv    128  1 x 1 / 1    38 x  38 x 256   ->    38 x  38 x 128  0.095 BFLOPs
   97 upsample            2x    38 x  38 x 128   ->    76 x  76 x 128
   98 route  97 36
   99 conv    128  1 x 1 / 1    76 x  76 x 384   ->    76 x  76 x 128  0.568 BFLOPs
  100 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  101 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
  102 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  103 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
  104 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  105 conv     18  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x  18  0.053 BFLOPs
  106 yolo
Loading weights from ../backup/rsna_yolov3_15300.weights...Done!
../test.jpg: Predicted in 35.566967 seconds.
pneumonia: 65%
pneumonia: 29%
pneumonia: 16%
pneumonia: 5%
pneumonia: 3%
In [ ]:
plt.imshow(cv2.imread("./darknet/predictions.jpg"))
Out[ ]:
<matplotlib.image.AxesImage at 0x794477503160>

Actual Bounding Box Information for the Patient

In [ ]:
sample_id = '76f71a93-8105-4c79-a010-0cfa86f0061a'
display_one_image(sample_id, four_bbox_df[four_bbox_df['patientId'] == sample_id])

Observation

Due to its anchor box design and large stride, YOLOv3 struggles to detect smaller objects. There is High Memory Requirements: YOLOv3 requires a significant amount of memory to run, which can be a challenge for devices with limited resources. The model was able to predict test images but was failing when the complete test folder was given as input for prediction due to memory issues. Hence, more powerful and better computational environment needs to be used for generating the prediction.

YOLOv3 Advantages

  • Fast and Efficient: YOLOv3 is designed to be fast and efficient, making it ideal for real-time applications such as self-driving cars and surveillance systems.

  • High Accuracy: YOLOv3 can achieve high accuracy in object detection while still being fast, thanks to its feature pyramid network and prediction module.

  • One-Stage Detection: Unlike traditional object detection models that use multiple stages, YOLOv3 uses a single neural network for detection, making it simpler and easier to implement.

  • Generalization: YOLOv3 can detect objects in a wide range of settings and scenarios, making it a versatile model.

An example of YOLOv3's advantages can be seen in self-driving cars, where real-time object detection is critical for the car's safety. YOLOv3's speed and accuracy can help the car detect objects such as pedestrians, other vehicles, and traffic signals quickly and react accordingly.

YOLOv3 Disadvantages

  • Smaller Objects Detection: YOLOv3 can struggle to detect smaller objects due to its anchor box design and large stride.

  • High Memory Requirements: YOLOv3 requires a significant amount of memory to run, which can be a challenge for devices with limited resources.

  • Training Time: Training YOLOv3 can be time-consuming, requiring large amounts of data and computational resources.

Generating Final Submission File¶

In [ ]:
 detection_threshold = 0.8
 results = []
 model.eval()
 with torch.no_grad():
    for i, image in tqdm(enumerate(test_images), total=len(test_images)):

         # plot image
         orig_image = pydicom.read_file(os.path.join(images_test_path + '%s' % image))
         image = orig_image.pixel_array

         image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)
         image /= 255.0
         image = np.transpose(image, (2, 0, 1)).astype(np.float32)
         image = torch.tensor(image, dtype=torch.float).cuda()
         image = torch.unsqueeze(image, 0)

         model.eval()
         cpu_device = torch.device("cpu")

         outputs = model(image)

         outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
         if len(outputs[0]['boxes']) != 0:
             for counter in range(len(outputs[0]['boxes'])):
                 boxes = outputs[0]['boxes'].data.cpu().numpy()
                 scores = outputs[0]['scores'].data.cpu().numpy()
                 boxes = boxes[scores >= detection_threshold].astype(np.int32)
                 draw_boxes = boxes.copy()
                 boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
                 boxes[:, 3] = boxes[:, 3] - boxes[:, 1]

                 draw_boxes = boxes.copy()

             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': format_prediction_string(boxes, scores)
            }
             results.append(result)
         else:
             result = {
                'patientId': test_images[i].split('.')[0],
                'PredictionString': ''
            }
             results.append(result)

 sub_df = pd.DataFrame(results, columns=['patientId', 'PredictionString'])
 print(sub_df.head())
 sub_df.to_csv('submission_frcnn.csv', index=False)
100%|██████████| 3000/3000 [06:00<00:00,  8.33it/s]
                              patientId  \
0  12abc170-f1fe-45d3-b574-2f4d030e40cd   
1  2abcf934-facd-40fc-a75e-0062441fd206   
2  2da69f80-c59d-4e4a-b7e5-1d631ef4186b   
3  13e4e6e6-faa2-4bbc-8e1e-610623de994e   
4  2afe02a3-06da-42fa-b68f-3e9c921e5fb9   

                                PredictionString  
0                                                 
1  0.9593 561 275 173 436 0.9328 197 298 181 341  
2                         0.8360 235 456 146 139  
3                                                 
4                                                 

Prediction of bounding boxes with Confidence Score for the test images. Out of total of 3000 images, 1098 images have been detected as Pneumonia cases with one or more bounding boxes.

In [ ]:
sub_df[sub_df['PredictionString']!='']
Out[ ]:
patientId PredictionString
1 2abcf934-facd-40fc-a75e-0062441fd206 0.9593 561 275 173 436 0.9328 197 298 181 341
2 2da69f80-c59d-4e4a-b7e5-1d631ef4186b 0.8360 235 456 146 139
6 2a7df7aa-1314-40da-afc5-7af58ad1bee9 0.9230 142 344 211 421
8 0de33fbf-998c-4c91-9561-df7343873bc2 0.9313 646 533 184 193
9 1eeecd10-16a2-476f-8d81-867d5480bf01 0.9270 256 481 176 151 0.8682 637 438 173 228
... ... ...
2985 140ebc5d-5a15-4948-b698-0a4b32d12a93 0.8276 144 359 228 491
2989 26586d01-b992-41c4-a7a4-c9f1f8d102ad 0.9242 192 396 212 336 0.8151 625 434 189 383
2990 23ebfb85-2312-4a8b-8879-3cf48a1e8920 0.9041 646 367 200 382
2991 2dbac7d7-9100-4861-8e15-fa2adf82c6e3 0.8707 758 264 217 432 0.8068 285 252 240 408
2997 20da1944-1714-4170-a08a-8b82c0788ad5 0.8825 200 502 197 113

1098 rows × 2 columns

For Demonstration purposes, displaying sample images with actual and predicted bounding box.

In [ ]:
#1352a7f3-1f0d-4f1f-af05-daa5d7f8624a
dataset = valid_df
f, axarr = plt.subplots(6, 2, figsize=(16,36))
axarr = axarr.ravel()
axidx = 0

image_id = valid_df.sample(6)['patientId'].reset_index(drop=True)
for i in range(6):

    show_image_with_bboxes(image_id[i],axarr,axidx)
    axidx+=1
    show_pred_image_with_bboxes(image_id[i],axarr,axidx)
    axidx+=1

Pickle the final Model for future use¶

Yolov3 was able to predict the test images with good performace. But Faster-RCNN predicted 1098 test images out of 3000 samples with high confidence score. Hence, pickle Faster RCNN model for further tuning in next phase of project.

In [ ]:
torch.save(model.state_dict(), 'fasterrcnn_resnet50_fpn_pneumonia_detection.pth')

Project Conclusion and future work¶

We tried various models to achieve our goal of building a model with minimal computational resources so that faster and accurate results can be brought out in the healthcare industry, especially the imaging side as it is very computationally heavy. Using the existing data, it was possible to train several models with different configurations and parameters whose accuracies vary between ∼74% and ∼97%; we can conclude that the model's capabilities can be expanded if sufficient training data and advanced computational capability to run further iterations is available as the loss was still decreasing.

In this work, we have presented our approach for identifying pneumonia and understanding how the lung image size plays an important role for the model performance. We found that the distinction is quite subtle for images among presence or absence of pneumonia, large image can be more beneficial for deeper information. However, the computation cost also burden exponentially when dealing with large image.

Our proposed architecture with regional context RCNN with selective search supplied extra context for generating accurate results. Also, using thresholds in background while training tuned our network to perform well in this task. With the usage of image augmentation, dropout and L2 regularization prevented the overfitting, but are obtained something weaker results on the training set with respect to the test. Our model can be improved by adding new layers, but this would introduce even more hyperparameters that should be adjusted. We intend to extend our model architecture in other areas of medical imaging with the usage of deep learning and computer vision techniques.

RCNN with selective search has very limited application for Dicom image analysis due to its architecture. The performance of other models has been better as compared to RCNN. Yolov3 was able to predict the test images with good performance. But Faster-RCNN predicted 1098 test images out of 3000 samples with high confidence score. Hence, both YOLO and Faster RCNN can be taken up for further tuning in next phase of project.

Improvements Area:

  • Due to memory and GPU requirements, not all training data could be loaded. This can be fully used for better model training.
  • Running the training for more epocs with higher patience levels
  • Increasing the image dimension being used from 224 to 512px or above.
  • Stratified sampling of data for training gives the model less opportunity of learning the needed feature in turn leaving the model with fewer accuracies as here only 1/3rd data is of the positive class.
  • Different variants of image augmentation can be tried.

While the results are promising, there are several avenues for future research: • Clinical Validation: Our model needs to be tested in a real-world clinical setting to assess its efficacy and reliability further. • Model Explainability: Future work can also focus on making the model more interpretable for clinicians, possibly through the use of attention mechanisms or other explainability techniques. • Multi-Modal Approaches: Incorporating additional data types, like patient history or other diagnostic tests, could potentially improve the model's predictive power. • Low-Resource Settings: Optimizing the model for deployment in low-resource settings could have a significant impact, making high-quality diagnosis accessible to underserved populations.

In future, it would be interesting to see or use medical dataset repository as it would be instrumental in advancing computer vision and deep learning research for medical field. As more and more advanced architectures are emerging, we can look at more accurate classification and localization models to diagnose pneumonia. We could also look at a historical progressive monitoring of the patient and affected region, assisting the pulmonologist in a visual analysis of the patient’s on-going condition.